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 d06e6ddada4..fccbbcdffc8 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 @@ -391,8 +391,9 @@ default: `indy-with-constants` for JVM target 9 or greater, `inline` otherwise"" @Argument( value = "-Xjdk-release", valueDescription = "", - description = """Compile against specified JDK API. Requires JDK 9 or newer. -Supported versions depend on used JDK (For JDK 17 supported targets are 1.8, 9, 10 - 17). Also set `-jvm-target` value""" + description = """Compile against the specified JDK API version, similarly to javac's `-release`. Requires JDK 9 or newer. +Supported versions depend on the used JDK; for JDK 17+ supported versions are 1.8, 9, 10, ..., 17. +Also sets `-jvm-target` value equal to the selected JDK version""" ) var jdkRelease: String? by NullableStringFreezableVar(null) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/ClasspathRootsResolver.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/ClasspathRootsResolver.kt index 0152c198859..647f885920a 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/ClasspathRootsResolver.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/ClasspathRootsResolver.kt @@ -56,7 +56,7 @@ class ClasspathRootsResolver( private val requireStdlibModule: Boolean, private val outputDirectory: VirtualFile?, private val javaFileManager: KotlinCliJavaFileManager, - private val release: Int + private val jdkRelease: Int ) { val javaModuleGraph = JavaModuleGraph(javaModuleFinder) @@ -125,7 +125,7 @@ class ClasspathRootsResolver( modules += module } } - if (release <= 0 || release >= 9) { + if (jdkRelease <= 0 || jdkRelease >= 9) { addModularRoots(modules, result) } else { //TODO: see also `addJvmSdkRoots` usages, some refactoring is required with moving such logic into one place @@ -285,13 +285,13 @@ class ClasspathRootsResolver( if (module == null) { report(ERROR, "Module $moduleName cannot be found in the module graph") } else { - for ((root, isBinary, isBinarySignature) in module.moduleRoots) { - result.add( - JavaRoot( - root, - if (isBinarySignature) JavaRoot.RootType.BINARY_SIG else if (isBinary) JavaRoot.RootType.BINARY else JavaRoot.RootType.SOURCE - ) - ) + module.moduleRoots.mapTo(result) { (root, isBinary, isBinarySignature) -> + val type = when { + isBinarySignature -> JavaRoot.RootType.BINARY_SIG + isBinary -> JavaRoot.RootType.BINARY + else -> JavaRoot.RootType.SOURCE + } + JavaRoot(root, type) } } } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliVirtualFileFinder.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliVirtualFileFinder.kt index 08e716698f9..7460704566c 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliVirtualFileFinder.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliVirtualFileFinder.kt @@ -78,7 +78,8 @@ class CliVirtualFileFinder( private fun findBinaryOrSigClass(classId: ClassId, simpleName: String, rootType: Set) = index.findClass(classId, acceptedRootTypes = rootType) { dir, _ -> - (dir.findChild("$simpleName.class") ?: findSigFileIfEnabled(dir, simpleName))?.takeIf(VirtualFile::isValid) + val file = dir.findChild("$simpleName.class") ?: findSigFileIfEnabled(dir, simpleName) + if (file != null && file.isValid) file else null }?.takeIf { it in scope } private fun findBinaryOrSigClass(classId: ClassId) = diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt index 74765813345..0ae24646f0f 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt @@ -29,30 +29,24 @@ fun CompilerConfiguration.setupJvmSpecificArguments(arguments: K2JVMCompilerArgu val jvmTargetArg = arguments.jvmTarget if (releaseTargetArg != null) { val value = - if (releaseTargetArg == "1.6" || releaseTargetArg == "1.8") releaseTargetArg.substringAfter("1.").toIntOrNull() - else releaseTargetArg.toIntOrNull() - if (value == null) { - messageCollector.report( - ERROR, - "Can't parse value passed for `-Xrelease`: $releaseTargetArg." - ) + when (releaseTargetArg) { + "1.6" -> 6 + "1.8" -> 8 + else -> releaseTargetArg.toIntOrNull() + } + if (value == null || value < 6) { + messageCollector.report(ERROR, "Unknown JDK release version: $releaseTargetArg") } else { - if (value < 6) { + //don't use release flag if it equals to compilation JDK version + if (value != getJavaVersion() || arguments.jdkHome != null) { + put(JVMConfigurationKeys.JDK_RELEASE, value) + } + if (jvmTargetArg != null && jvmTargetArg != releaseTargetArg) { messageCollector.report( ERROR, - "`$value` is not valid value for `-Xrelease` flag." + "'-Xjdk-release=$releaseTargetArg' option conflicts with '-jvm-target $jvmTargetArg'. " + + "Please remove the '-jvm-target' option" ) - } else { - //don't use release flag if it equals to compilation JDK version - if (value != getJavaVersion() || arguments.jdkHome != null) { - put(JVMConfigurationKeys.JDK_RELEASE, value) - } - if (jvmTargetArg != null && jvmTargetArg != releaseTargetArg) { - messageCollector.report( - ERROR, - "`-Xrelease=$releaseTargetArg` option conflicts with '-jvm-target=$jvmTargetArg'." - ) - } } } } @@ -76,11 +70,6 @@ fun CompilerConfiguration.setupJvmSpecificArguments(arguments: K2JVMCompilerArgu } } - if (get(JVMConfigurationKeys.JVM_TARGET) == null) { - put(JVMConfigurationKeys.JVM_TARGET, JvmTarget.JVM_1_8) - } - - val jvmTarget = get(JVMConfigurationKeys.JVM_TARGET) ?: JvmTarget.DEFAULT if (jvmTarget.majorVersion < JvmTarget.JVM_1_8.majorVersion) { val jvmDefaultMode = languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode) @@ -185,8 +174,8 @@ fun CompilerConfiguration.configureExplicitContentRoots(arguments: K2JVMCompiler } fun CompilerConfiguration.configureStandardLibs(paths: KotlinPaths?, arguments: K2JVMCompilerArguments) { - val releaseFlagValue = this.get(JVMConfigurationKeys.JDK_RELEASE, 0) - val isModularJava = isModularJava() && (releaseFlagValue <= 0 || releaseFlagValue >= 9) + val jdkRelease = get(JVMConfigurationKeys.JDK_RELEASE) + val isModularJava = isModularJava() && (jdkRelease == null || jdkRelease >= 9) fun addRoot(moduleName: String, libraryName: String, getLibrary: (KotlinPaths) -> File, noLibraryArgument: String) { addModularRootIfNotNull( diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleFinder.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleFinder.kt index 8025084eade..905dd89edce 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleFinder.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleFinder.kt @@ -52,22 +52,22 @@ class CliJavaModuleFinder( private val ctSymFile: VirtualFile? by lazy { if (jdkHome == null) return@lazy reportError("JDK_HOME path is not specified in compiler configuration") - val jdkRootFile = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL).findFileByPath(jdkHome.path) + val jdkRootFile = StandardFileSystems.local().findFileByPath(jdkHome.path) ?: return@lazy reportError("Can't create virtual file for JDK root under ${jdkHome.path}") val lib = jdkRootFile.findChild("lib") ?: return@lazy reportError("Can't find `lib` folder under JDK root: ${jdkHome.path}") - val ctSym = lib.findChild("ct.sym") ?: return@lazy reportError("Can't find `ct.sym` file in ${jdkHome.path}") - - if (!ctSym.isValid) return@lazy reportError("`ct.sym` is invalid: ${ctSym.path}") - + val ctSym = lib.findChild("ct.sym") + ?: return@lazy reportError( + "This JDK does not have the 'ct.sym' file required for the '-Xjdk-release=$releaseTarget' option: ${jdkHome.path}" + ) + ctSym } private val ctSymRootFolder: VirtualFile? by lazy { if (ctSymFile != null) { - VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JAR_PROTOCOL) - ?.findFileByPath(ctSymFile?.path + URLUtil.JAR_SEPARATOR) + StandardFileSystems.jar()?.findFileByPath(ctSymFile?.path + URLUtil.JAR_SEPARATOR) ?: reportError("Can't open `ct.sym` as jar file, file path: ${ctSymFile?.path} ") } else { null @@ -132,10 +132,8 @@ class CliJavaModuleFinder( if (isCompilationJDK12OrLater) emptyMap() else hashMapOf().also { parts -> moduleInfo.exports.forEach { - it.packageFqName.pathSegments().fold("") { acc, v -> - val packagePart = if (acc.isEmpty()) v.asString() else "$acc.${v.asString()}" - parts[packagePart] = false - packagePart + for (part in generateSequence(it.packageFqName) { part -> if (!part.isRoot) part.parent() else null }) { + parts[part.asString()] = false } } //Do it separately to avoid reset to false diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index 6d2f65f2649..00b4e90282e 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -35,8 +35,9 @@ where advanced options include: -Xjava-package-prefix Package prefix for Java files -Xjava-source-roots= Paths to directories with Java source files -Xjavac-arguments= Java compiler arguments - -Xjdk-release= Compile against specified JDK API. Requires JDK 9 or newer. - Supported versions depend on used JDK (For JDK 17 supported targets are 1.8, 9, 10 - 17). Also set `-jvm-target` value + -Xjdk-release= Compile against the specified JDK API version, similarly to javac's `-release`. Requires JDK 9 or newer. + Supported versions depend on the used JDK; for JDK 17+ supported versions are 1.8, 9, 10, ..., 17. + Also sets `-jvm-target` value equal to the selected JDK version -Xjspecify-annotations=ignore|strict|warn Specify behavior for jspecify annotations. Default value is 'warn' diff --git a/compiler/testData/javaModules/releaseFlagConflict/module11.txt b/compiler/testData/javaModules/releaseFlagConflict/module11.txt index e4544816b30..93cbd198c6d 100644 --- a/compiler/testData/javaModules/releaseFlagConflict/module11.txt +++ b/compiler/testData/javaModules/releaseFlagConflict/module11.txt @@ -1,2 +1,2 @@ -error: `-Xrelease=11` option conflicts with '-jvm-target=10'. +error: '-Xjdk-release=11' option conflicts with '-jvm-target 10'. Please remove the '-jvm-target' option COMPILATION_ERROR diff --git a/compiler/testData/javaModules/releaseFlagConflict/module9.txt b/compiler/testData/javaModules/releaseFlagConflict/module9.txt index 29e6b8b9b1a..79f51ef518e 100644 --- a/compiler/testData/javaModules/releaseFlagConflict/module9.txt +++ b/compiler/testData/javaModules/releaseFlagConflict/module9.txt @@ -1,2 +1,2 @@ -error: `-Xrelease=9` option conflicts with '-jvm-target=10'. +error: '-Xjdk-release=9' option conflicts with '-jvm-target 10'. Please remove the '-jvm-target' option COMPILATION_ERROR diff --git a/compiler/testData/javaModules/releaseFlagWrongValue/module5.txt b/compiler/testData/javaModules/releaseFlagWrongValue/module5.txt index 3e84705198a..fdb48415804 100644 --- a/compiler/testData/javaModules/releaseFlagWrongValue/module5.txt +++ b/compiler/testData/javaModules/releaseFlagWrongValue/module5.txt @@ -1,4 +1,4 @@ -error: `5` is not valid value for `-Xrelease` flag. +error: unknown JDK release version: 5 error: unknown JVM target version: 5 Supported versions: 1.6, 1.8, 9, 10, 11, 12, 13, 14, 15, 16, 17 COMPILATION_ERROR diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java11ModulesIntegrationTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java11ModulesIntegrationTest.kt index d5c76eb391b..747e5db64e5 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java11ModulesIntegrationTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java11ModulesIntegrationTest.kt @@ -149,23 +149,17 @@ class Java11ModulesIntegrationTest : AbstractKotlinCompilerIntegrationTest() { } fun testReleaseFlagWrongValue() { - // Test that although we have moduleA in the module path, it's not in the module graph - // because we did not provide -Xadd-modules=moduleA module("module5", additionalKotlinArguments = listOf("-Xjdk-release=5")) module("module12", additionalKotlinArguments = listOf("-Xjdk-release=12")) } fun testReleaseFlag() { - // Test that although we have moduleA in the module path, it's not in the module graph - // because we did not provide -Xadd-modules=moduleA module("module") module("module11", additionalKotlinArguments = listOf("-Xjdk-release=11")) module("moduleSwing", additionalKotlinArguments = listOf("-Xjdk-release=9")) } fun testReleaseFlagConflict() { - // Test that although we have moduleA in the module path, it's not in the module graph - // because we did not provide -Xadd-modules=moduleA module("module9", additionalKotlinArguments = listOf("-Xjdk-release=9", "-jvm-target=10")) module("module11", additionalKotlinArguments = listOf("-Xjdk-release=11", "-jvm-target=10")) }