Separate JVM target option from javac's --enable-preview analogue
This commit is contained in:
@@ -272,7 +272,10 @@ class GenerationState private constructor(
|
|||||||
|
|
||||||
val rootContext: CodegenContext<*> = RootContext(this)
|
val rootContext: CodegenContext<*> = RootContext(this)
|
||||||
|
|
||||||
val classFileVersion: Int = target.bytecodeVersion
|
val classFileVersion: Int = run {
|
||||||
|
val minorVersion = if (configuration.getBoolean(JVMConfigurationKeys.ENABLE_JVM_PREVIEW)) 0xffff else 0
|
||||||
|
(minorVersion shl 16) + target.majorVersion
|
||||||
|
}
|
||||||
|
|
||||||
val generateParametersMetadata: Boolean = configuration.getBoolean(JVMConfigurationKeys.PARAMETERS_METADATA)
|
val generateParametersMetadata: Boolean = configuration.getBoolean(JVMConfigurationKeys.PARAMETERS_METADATA)
|
||||||
|
|
||||||
|
|||||||
+7
@@ -418,6 +418,13 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
|||||||
)
|
)
|
||||||
var useOldInlineClassesManglingScheme: Boolean by FreezableVar(false)
|
var useOldInlineClassesManglingScheme: Boolean by FreezableVar(false)
|
||||||
|
|
||||||
|
@Argument(
|
||||||
|
value = "-Xjvm-enable-preview",
|
||||||
|
description = "Allow using features from Java language that are in preview phase.\n" +
|
||||||
|
"Works as `--enable-preview` in Java. All class files are marked as preview-generated thus it won't be possible to use them in release environment"
|
||||||
|
)
|
||||||
|
var enableJvmPreview: Boolean by FreezableVar(false)
|
||||||
|
|
||||||
override fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
|
override fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
|
||||||
val result = super.configureAnalysisFlags(collector)
|
val result = super.configureAnalysisFlags(collector)
|
||||||
result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics
|
result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics
|
||||||
|
|||||||
@@ -67,19 +67,19 @@ fun CompilerConfiguration.setupJvmSpecificArguments(arguments: K2JVMCompilerArgu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (languageVersionSettings.supportsFeature(LanguageFeature.JvmRecordSupport) && !jvmTarget.isRecordsAllowed()) {
|
if (languageVersionSettings.supportsFeature(LanguageFeature.JvmRecordSupport) && !jvmTarget.areRecordsAllowed(arguments.enableJvmPreview)) {
|
||||||
messageCollector.report(
|
messageCollector.report(
|
||||||
ERROR,
|
ERROR,
|
||||||
"-XXLanguage:+${LanguageFeature.JvmRecordSupport} feature is only supported with JVM target ${JvmTarget.JVM_15_PREVIEW.description} or later"
|
"-XXLanguage:+${LanguageFeature.JvmRecordSupport} feature is only supported with JVM target ${JvmTarget.JVM_15.description} or later"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
addAll(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES, arguments.additionalJavaModules?.asList())
|
addAll(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES, arguments.additionalJavaModules?.asList())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JvmTarget.isRecordsAllowed(): Boolean {
|
private fun JvmTarget.areRecordsAllowed(enableJvmPreview: Boolean): Boolean {
|
||||||
if (majorVersion < JvmTarget.JVM_15_PREVIEW.majorVersion) return false
|
if (majorVersion < JvmTarget.JVM_15.majorVersion) return false
|
||||||
return isPreview || majorVersion > JvmTarget.JVM_15_PREVIEW.majorVersion
|
return enableJvmPreview || majorVersion > JvmTarget.JVM_15.majorVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
fun CompilerConfiguration.configureJdkHome(arguments: K2JVMCompilerArguments): Boolean {
|
fun CompilerConfiguration.configureJdkHome(arguments: K2JVMCompilerArguments): Boolean {
|
||||||
@@ -244,6 +244,12 @@ fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerAr
|
|||||||
put(JVMConfigurationKeys.USE_SINGLE_MODULE, arguments.singleModule)
|
put(JVMConfigurationKeys.USE_SINGLE_MODULE, arguments.singleModule)
|
||||||
put(JVMConfigurationKeys.USE_OLD_SPILLED_VAR_TYPE_ANALYSIS, arguments.useOldSpilledVarTypeAnalysis)
|
put(JVMConfigurationKeys.USE_OLD_SPILLED_VAR_TYPE_ANALYSIS, arguments.useOldSpilledVarTypeAnalysis)
|
||||||
put(JVMConfigurationKeys.USE_OLD_INLINE_CLASSES_MANGLING_SCHEME, arguments.useOldInlineClassesManglingScheme)
|
put(JVMConfigurationKeys.USE_OLD_INLINE_CLASSES_MANGLING_SCHEME, arguments.useOldInlineClassesManglingScheme)
|
||||||
|
put(JVMConfigurationKeys.ENABLE_JVM_PREVIEW, arguments.enableJvmPreview)
|
||||||
|
|
||||||
|
if (arguments.enableJvmPreview) {
|
||||||
|
getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||||
|
.report(INFO, "Using preview Java language features")
|
||||||
|
}
|
||||||
|
|
||||||
arguments.declarationsOutputPath?.let { put(JVMConfigurationKeys.DECLARATIONS_JSON_PATH, it) }
|
arguments.declarationsOutputPath?.let { put(JVMConfigurationKeys.DECLARATIONS_JSON_PATH, it) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,4 +140,7 @@ public class JVMConfigurationKeys {
|
|||||||
|
|
||||||
public static final CompilerConfigurationKey<Boolean> USE_OLD_INLINE_CLASSES_MANGLING_SCHEME =
|
public static final CompilerConfigurationKey<Boolean> USE_OLD_INLINE_CLASSES_MANGLING_SCHEME =
|
||||||
CompilerConfigurationKey.create("Use old, 1.4 version of inline classes mangling scheme");
|
CompilerConfigurationKey.create("Use old, 1.4 version of inline classes mangling scheme");
|
||||||
|
|
||||||
|
public static final CompilerConfigurationKey<Boolean> ENABLE_JVM_PREVIEW =
|
||||||
|
CompilerConfigurationKey.create("Enable Java language preview features");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,6 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
|||||||
enum class JvmTarget(
|
enum class JvmTarget(
|
||||||
override val description: String,
|
override val description: String,
|
||||||
val majorVersion: Int,
|
val majorVersion: Int,
|
||||||
val descriptionForJavacArgument: String = description,
|
|
||||||
val isPreview: Boolean = false,
|
|
||||||
) : TargetPlatformVersion {
|
) : TargetPlatformVersion {
|
||||||
JVM_1_6("1.6", Opcodes.V1_6),
|
JVM_1_6("1.6", Opcodes.V1_6),
|
||||||
JVM_1_8("1.8", Opcodes.V1_8),
|
JVM_1_8("1.8", Opcodes.V1_8),
|
||||||
@@ -34,22 +32,8 @@ enum class JvmTarget(
|
|||||||
JVM_13("13", Opcodes.V13),
|
JVM_13("13", Opcodes.V13),
|
||||||
JVM_14("14", Opcodes.V14),
|
JVM_14("14", Opcodes.V14),
|
||||||
JVM_15("15", Opcodes.V15),
|
JVM_15("15", Opcodes.V15),
|
||||||
JVM_15_PREVIEW(
|
|
||||||
"15_PREVIEW", Opcodes.V15,
|
|
||||||
descriptionForJavacArgument = "15", isPreview = true
|
|
||||||
),
|
|
||||||
;
|
;
|
||||||
|
|
||||||
val minorVersion: Int =
|
|
||||||
if (isPreview)
|
|
||||||
0xffff
|
|
||||||
else
|
|
||||||
0
|
|
||||||
|
|
||||||
val bytecodeVersion: Int by lazy {
|
|
||||||
(minorVersion shl 16) + majorVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
@JvmField
|
||||||
val DEFAULT = JVM_1_6
|
val DEFAULT = JVM_1_6
|
||||||
@@ -57,14 +41,14 @@ enum class JvmTarget(
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun fromString(string: String) = values().find { it.description == string }
|
fun fromString(string: String) = values().find { it.description == string }
|
||||||
|
|
||||||
fun getDescription(bytecodeVersion: Int): String {
|
fun getDescription(majorVersion: Int): String {
|
||||||
val platformDescription = values().find { it.bytecodeVersion == bytecodeVersion }?.description ?: when (bytecodeVersion) {
|
val platformDescription = values().find { it.majorVersion == majorVersion }?.description ?: when (majorVersion) {
|
||||||
Opcodes.V1_7 -> "1.7"
|
Opcodes.V1_7 -> "1.7"
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (platformDescription != null) "JVM target $platformDescription"
|
return if (platformDescription != null) "JVM target $platformDescription"
|
||||||
else "JVM bytecode version $bytecodeVersion"
|
else "JVM bytecode version $majorVersion"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -22,6 +22,8 @@ where advanced options include:
|
|||||||
-Xir-do-not-clear-binding-context
|
-Xir-do-not-clear-binding-context
|
||||||
When using the IR backend, do not clear BindingContext between psi2ir and lowerings
|
When using the IR backend, do not clear BindingContext between psi2ir and lowerings
|
||||||
-Xemit-jvm-type-annotations Emit JVM type annotations in bytecode
|
-Xemit-jvm-type-annotations Emit JVM type annotations in bytecode
|
||||||
|
-Xjvm-enable-preview Allow using features from Java language that are in preview phase.
|
||||||
|
Works as `--enable-preview` in Java. All class files are marked as preview-generated thus it won't be possible to use them in release environment
|
||||||
-Xfriend-paths=<path> Paths to output directories for friend modules (whose internals should be visible)
|
-Xfriend-paths=<path> Paths to output directories for friend modules (whose internals should be visible)
|
||||||
-Xmultifile-parts-inherit Compile multifile classes as a hierarchy of parts and facade
|
-Xmultifile-parts-inherit Compile multifile classes as a hierarchy of parts and facade
|
||||||
-Xir-check-local-names Check that names of local classes and anonymous objects are the same in the IR backend as in the old backend
|
-Xir-check-local-names Check that names of local classes and anonymous objects are the same in the IR backend as in the old backend
|
||||||
|
|||||||
+2
-1
@@ -8,5 +8,6 @@ $TEMP_DIR$
|
|||||||
-jdk-home
|
-jdk-home
|
||||||
$JDK_15$
|
$JDK_15$
|
||||||
-XXLanguage:+JvmRecordSupport
|
-XXLanguage:+JvmRecordSupport
|
||||||
|
-Xjvm-enable-preview
|
||||||
-jvm-target
|
-jvm-target
|
||||||
15_PREVIEW
|
15
|
||||||
|
|||||||
+2
@@ -7,4 +7,6 @@ This mode is not recommended for production use,
|
|||||||
as no stability/compatibility guarantees are given on
|
as no stability/compatibility guarantees are given on
|
||||||
compiler or generated code. Use it at your own risk!
|
compiler or generated code. Use it at your own risk!
|
||||||
|
|
||||||
|
warning: language version 1.5 is experimental, there are no backwards compatibility guarantees for new language and library features
|
||||||
|
info: using preview Java language features
|
||||||
OK
|
OK
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
error: unknown JVM target version: 1.5
|
error: unknown JVM target version: 1.5
|
||||||
Supported versions: 1.6, 1.8, 9, 10, 11, 12, 13, 14, 15, 15_PREVIEW
|
Supported versions: 1.6, 1.8, 9, 10, 11, 12, 13, 14, 15
|
||||||
COMPILATION_ERROR
|
COMPILATION_ERROR
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// !API_VERSION: 1.5
|
// !API_VERSION: 1.5
|
||||||
// !LANGUAGE: +JvmRecordSupport
|
// !LANGUAGE: +JvmRecordSupport
|
||||||
// JVM_TARGET: 15_PREVIEW
|
// JVM_TARGET: 15
|
||||||
|
// ENABLE_JVM_PREVIEW
|
||||||
// FILE: JavaClass.java
|
// FILE: JavaClass.java
|
||||||
public class JavaClass {
|
public class JavaClass {
|
||||||
public static String box() {
|
public static String box() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// !API_VERSION: 1.5
|
// !API_VERSION: 1.5
|
||||||
// !LANGUAGE: +JvmRecordSupport
|
// !LANGUAGE: +JvmRecordSupport
|
||||||
// JVM_TARGET: 15_PREVIEW
|
// JVM_TARGET: 15
|
||||||
|
// ENABLE_JVM_PREVIEW
|
||||||
|
|
||||||
@JvmRecord
|
@JvmRecord
|
||||||
data class MyRec<R>(val x: String, val y: R)
|
data class MyRec<R>(val x: String, val y: R)
|
||||||
|
|||||||
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
// JVM_TARGET: 15_PREVIEW
|
// JVM_TARGET: 15
|
||||||
|
// ENABLE_JVM_PREVIEW
|
||||||
// FILE: MyRec.java
|
// FILE: MyRec.java
|
||||||
public record MyRec(String name) implements KI {
|
public record MyRec(String name) implements KI {
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
|||||||
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
// JVM_TARGET: 15_PREVIEW
|
// JVM_TARGET: 15
|
||||||
|
// ENABLE_JVM_PREVIEW
|
||||||
// FILE: MyRec.java
|
// FILE: MyRec.java
|
||||||
public record MyRec(String name) {
|
public record MyRec(String name) {
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// !LANGUAGE: +JvmRecordSupport
|
// !LANGUAGE: +JvmRecordSupport
|
||||||
// JVM_TARGET: 15_PREVIEW
|
// JVM_TARGET: 15
|
||||||
|
// ENABLE_JVM_PREVIEW
|
||||||
// FILE: MyRec.java
|
// FILE: MyRec.java
|
||||||
public record MyRec(String name) {}
|
public record MyRec(String name) {}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// !API_VERSION: 1.5
|
// !API_VERSION: 1.5
|
||||||
// !LANGUAGE: +JvmRecordSupport
|
// !LANGUAGE: +JvmRecordSupport
|
||||||
// JVM_TARGET: 15_PREVIEW
|
// JVM_TARGET: 15
|
||||||
|
// ENABLE_JVM_PREVIEW
|
||||||
// FILE: A.kt
|
// FILE: A.kt
|
||||||
@JvmRecord
|
@JvmRecord
|
||||||
data class MyRecord(val foo: String, val bar: String)
|
data class MyRecord(val foo: String, val bar: String)
|
||||||
|
|||||||
+8
-1
@@ -25,9 +25,16 @@ abstract class AbstractBlackBoxAgainstJavaCodegenTest : AbstractBlackBoxCodegenT
|
|||||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>) {
|
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>) {
|
||||||
javaClassesOutputDirectory = writeJavaFiles(files)!!.let { directory ->
|
javaClassesOutputDirectory = writeJavaFiles(files)!!.let { directory ->
|
||||||
val jvmTargets = files.mapNotNullTo(mutableSetOf()) { it.directives["JVM_TARGET"]?.let((JvmTarget)::fromString) }
|
val jvmTargets = files.mapNotNullTo(mutableSetOf()) { it.directives["JVM_TARGET"]?.let((JvmTarget)::fromString) }
|
||||||
|
val enablePreview = files.any { it.directives.contains("ENABLE_JVM_PREVIEW") }
|
||||||
check(jvmTargets.size <= 1) { "Having different JVM_TARGETs for different files is not supported in this test." }
|
check(jvmTargets.size <= 1) { "Having different JVM_TARGETs for different files is not supported in this test." }
|
||||||
CodegenTestUtil.compileJava(
|
CodegenTestUtil.compileJava(
|
||||||
CodegenTestUtil.findJavaSourcesInDirectory(directory), emptyList(), extractJavacOptions(files, jvmTargets.firstOrNull())
|
CodegenTestUtil.findJavaSourcesInDirectory(directory),
|
||||||
|
emptyList(),
|
||||||
|
extractJavacOptions(
|
||||||
|
files,
|
||||||
|
jvmTargets.firstOrNull(),
|
||||||
|
enablePreview,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -529,7 +529,11 @@ public abstract class CodegenTestCase extends KotlinBaseTest<KotlinBaseTest.Test
|
|||||||
updateJavaClasspath(javaClasspath);
|
updateJavaClasspath(javaClasspath);
|
||||||
|
|
||||||
javaClassesOutputDirectory = getJavaClassesOutputDirectory();
|
javaClassesOutputDirectory = getJavaClassesOutputDirectory();
|
||||||
List<String> javacOptions = extractJavacOptions(files, configuration.get(JVMConfigurationKeys.JVM_TARGET));
|
List<String> javacOptions = extractJavacOptions(
|
||||||
|
files,
|
||||||
|
configuration.get(JVMConfigurationKeys.JVM_TARGET),
|
||||||
|
configuration.getBoolean(JVMConfigurationKeys.ENABLE_JVM_PREVIEW)
|
||||||
|
);
|
||||||
List<String> finalJavacOptions = prepareJavacOptions(javaClasspath, javacOptions, javaClassesOutputDirectory);
|
List<String> finalJavacOptions = prepareJavacOptions(javaClasspath, javacOptions, javaClassesOutputDirectory);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -551,15 +555,19 @@ public abstract class CodegenTestCase extends KotlinBaseTest<KotlinBaseTest.Test
|
|||||||
protected void updateJavaClasspath(@NotNull List<String> javaClasspath) {}
|
protected void updateJavaClasspath(@NotNull List<String> javaClasspath) {}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
protected static List<String> extractJavacOptions(@NotNull List<TestFile> files, @Nullable JvmTarget kotlinTarget) {
|
protected static List<String> extractJavacOptions(
|
||||||
|
@NotNull List<TestFile> files,
|
||||||
|
@Nullable JvmTarget kotlinTarget,
|
||||||
|
boolean isJvmPreviewEnabled
|
||||||
|
) {
|
||||||
List<String> javacOptions = new ArrayList<>(0);
|
List<String> javacOptions = new ArrayList<>(0);
|
||||||
for (TestFile file : files) {
|
for (TestFile file : files) {
|
||||||
javacOptions.addAll(InTextDirectivesUtils.findListWithPrefixes(file.content, "// JAVAC_OPTIONS:"));
|
javacOptions.addAll(InTextDirectivesUtils.findListWithPrefixes(file.content, "// JAVAC_OPTIONS:"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kotlinTarget != null && kotlinTarget.isPreview()) {
|
if (kotlinTarget != null && isJvmPreviewEnabled) {
|
||||||
javacOptions.add("--release");
|
javacOptions.add("--release");
|
||||||
javacOptions.add(kotlinTarget.getDescriptionForJavacArgument());
|
javacOptions.add(kotlinTarget.getDescription());
|
||||||
javacOptions.add("--enable-preview");
|
javacOptions.add("--enable-preview");
|
||||||
return javacOptions;
|
return javacOptions;
|
||||||
}
|
}
|
||||||
@@ -582,7 +590,7 @@ public abstract class CodegenTestCase extends KotlinBaseTest<KotlinBaseTest.Test
|
|||||||
if (JAVA_COMPILATION_TARGET != null && !javacOptions.contains("-target"))
|
if (JAVA_COMPILATION_TARGET != null && !javacOptions.contains("-target"))
|
||||||
return JAVA_COMPILATION_TARGET;
|
return JAVA_COMPILATION_TARGET;
|
||||||
if (kotlinTarget != null && kotlinTarget.compareTo(JvmTarget.JVM_1_6) > 0)
|
if (kotlinTarget != null && kotlinTarget.compareTo(JvmTarget.JVM_1_6) > 0)
|
||||||
return kotlinTarget.getDescriptionForJavacArgument();
|
return kotlinTarget.getDescription();
|
||||||
if (IS_SOURCE_6_STILL_SUPPORTED)
|
if (IS_SOURCE_6_STILL_SUPPORTED)
|
||||||
return "1.6";
|
return "1.6";
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -227,6 +227,11 @@ abstract class KotlinBaseTest<F : KotlinBaseTest.TestFile> : KtUsefulTestCase()
|
|||||||
?: error("Unknown target: $targetString")
|
?: error("Unknown target: $targetString")
|
||||||
configuration.put(JVMConfigurationKeys.JVM_TARGET, jvmTarget)
|
configuration.put(JVMConfigurationKeys.JVM_TARGET, jvmTarget)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (directives.contains("ENABLE_JVM_PREVIEW")) {
|
||||||
|
configuration.put(JVMConfigurationKeys.ENABLE_JVM_PREVIEW, true)
|
||||||
|
}
|
||||||
|
|
||||||
val version = directives["LANGUAGE_VERSION"]
|
val version = directives["LANGUAGE_VERSION"]
|
||||||
if (version != null) {
|
if (version != null) {
|
||||||
throw AssertionError(
|
throw AssertionError(
|
||||||
|
|||||||
Reference in New Issue
Block a user