Basic -Xrelease option support
#KT-29974 Fixed
This commit is contained in:
+10
@@ -388,6 +388,16 @@ default: `indy-with-constants` for JVM target 9 or greater, `inline` otherwise""
|
||||
)
|
||||
var stringConcat: String? by NullableStringFreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-Xrelease",
|
||||
valueDescription = "Supported versions depend on used JDK",
|
||||
description = """
|
||||
Compile against specified JDK API. Supported versions depend on used JDK
|
||||
"""
|
||||
)
|
||||
var release: String? by NullableStringFreezableVar(null)
|
||||
|
||||
|
||||
@Argument(
|
||||
value = "-Xsam-conversions",
|
||||
valueDescription = "{class|indy}",
|
||||
|
||||
@@ -55,7 +55,8 @@ class ClasspathRootsResolver(
|
||||
private val javaModuleFinder: CliJavaModuleFinder,
|
||||
private val requireStdlibModule: Boolean,
|
||||
private val outputDirectory: VirtualFile?,
|
||||
private val javaFileManager: KotlinCliJavaFileManager
|
||||
private val javaFileManager: KotlinCliJavaFileManager,
|
||||
private val release: Int
|
||||
) {
|
||||
val javaModuleGraph = JavaModuleGraph(javaModuleFinder)
|
||||
|
||||
@@ -124,8 +125,15 @@ class ClasspathRootsResolver(
|
||||
modules += module
|
||||
}
|
||||
}
|
||||
|
||||
addModularRoots(modules, result)
|
||||
if (release <= 0 || release >= 9) {
|
||||
addModularRoots(modules, result)
|
||||
} else {
|
||||
//TODO: see also `addJvmSdkRoots` usages, some refactoring is required with moving such logic into one place
|
||||
val listFoldersForRelease = javaModuleFinder.listFoldersForRelease(release)
|
||||
listFoldersForRelease.forEach {
|
||||
result += JavaRoot(it, JavaRoot.RootType.BINARY_SIG)
|
||||
}
|
||||
}
|
||||
|
||||
return RootsAndModules(result, modules)
|
||||
}
|
||||
|
||||
@@ -241,6 +241,9 @@ class KotlinCoreEnvironment private constructor(
|
||||
val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME)
|
||||
val jrtFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL)
|
||||
val javaModuleFinder = CliJavaModuleFinder(
|
||||
jdkHome?.path?.let { path ->
|
||||
VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL).findFileByPath(path)
|
||||
},
|
||||
jdkHome?.path?.let { path ->
|
||||
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
|
||||
},
|
||||
@@ -260,7 +263,8 @@ class KotlinCoreEnvironment private constructor(
|
||||
javaModuleFinder,
|
||||
!configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE),
|
||||
outputDirectory?.let(this::findLocalFile),
|
||||
javaFileManager
|
||||
javaFileManager,
|
||||
configuration.get(JVMConfigurationKeys.RELEASE, 0)
|
||||
)
|
||||
|
||||
val (initialRoots, javaModules) =
|
||||
|
||||
@@ -73,6 +73,20 @@ fun CompilerConfiguration.setupJvmSpecificArguments(arguments: K2JVMCompilerArgu
|
||||
}
|
||||
}
|
||||
|
||||
val release = arguments.release
|
||||
if (release != null) {
|
||||
val value = release.toIntOrNull()
|
||||
if (value == null) {
|
||||
messageCollector.report(
|
||||
ERROR,
|
||||
"Can't parse value passed for `-Xrelease`: $release."
|
||||
)
|
||||
} else {
|
||||
// TODO: check
|
||||
put(JVMConfigurationKeys.RELEASE, value)
|
||||
}
|
||||
}
|
||||
|
||||
handleClosureGenerationSchemeArgument("-Xsam-conversions", arguments.samConversions, JVMConfigurationKeys.SAM_CONVERSIONS, jvmTarget)
|
||||
handleClosureGenerationSchemeArgument("-Xlambdas", arguments.lambdas, JVMConfigurationKeys.LAMBDAS, jvmTarget)
|
||||
|
||||
@@ -147,7 +161,8 @@ fun CompilerConfiguration.configureExplicitContentRoots(arguments: K2JVMCompiler
|
||||
}
|
||||
|
||||
fun CompilerConfiguration.configureStandardLibs(paths: KotlinPaths?, arguments: K2JVMCompilerArguments) {
|
||||
val isModularJava = isModularJava()
|
||||
val releaseFlagValue = this.get(JVMConfigurationKeys.RELEASE, 0)
|
||||
val isModularJava = isModularJava() && (releaseFlagValue <= 0 || releaseFlagValue >= 9)
|
||||
|
||||
fun addRoot(moduleName: String, libraryName: String, getLibrary: (KotlinPaths) -> File, noLibraryArgument: String) {
|
||||
addModularRootIfNotNull(
|
||||
|
||||
@@ -17,24 +17,41 @@
|
||||
package org.jetbrains.kotlin.cli.jvm.modules
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.psi.PsiJavaModule
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.util.io.URLUtil
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinCliJavaFileManager
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleFinder
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
|
||||
|
||||
class CliJavaModuleFinder(
|
||||
jdkRootFile: VirtualFile?,
|
||||
jrtFileSystemRoot: VirtualFile?,
|
||||
private val javaFileManager: KotlinCliJavaFileManager,
|
||||
project: Project
|
||||
) : JavaModuleFinder {
|
||||
private val modulesRoot = jrtFileSystemRoot?.findChild("modules")
|
||||
private val ctSymFile = jdkRootFile?.findChild("lib")?.findChild("ct.sym")
|
||||
private val userModules = linkedMapOf<String, JavaModule>()
|
||||
|
||||
private val allScope = GlobalSearchScope.allScope(project)
|
||||
|
||||
public val compilationJdkVersion by lazy {
|
||||
//TODO: add test with -jdk-home
|
||||
// Observe all JDK codes from folder name chars in ct.sym file,
|
||||
// there should be maximal one corresponding to used compilation JDK
|
||||
listFoldersInCtSym()?.children?.maxOf {
|
||||
if (it.name == "META-INF") -1
|
||||
else it.name.substringBeforeLast("-modules").maxOf { char ->
|
||||
char.toString().toIntOrNull(36) ?: -1
|
||||
}
|
||||
} ?: -1
|
||||
}
|
||||
|
||||
fun addUserModule(module: JavaModule) {
|
||||
userModules.putIfAbsent(module.name, module)
|
||||
}
|
||||
@@ -53,4 +70,27 @@ class CliJavaModuleFinder(
|
||||
val moduleInfo = JavaModuleInfo.read(file, javaFileManager, allScope) ?: return null
|
||||
return JavaModule.Explicit(moduleInfo, listOf(JavaModule.Root(moduleRoot, isBinary = true)), file)
|
||||
}
|
||||
|
||||
private fun codeFor(release: Int): String = release.toString(36).toUpperCase()
|
||||
|
||||
private fun matchesRelease(fileName: String, release: Int) =
|
||||
!fileName.contains("-") && fileName.contains(codeFor(release)) // skip `*-modules`
|
||||
|
||||
private fun hasCtSymFile() = ctSymFile != null && ctSymFile.isValid
|
||||
|
||||
fun listFoldersForRelease(release: Int): List<VirtualFile> {
|
||||
if (!hasCtSymFile()) return emptyList()
|
||||
val findFileByPath = listFoldersInCtSym() ?: return emptyList()
|
||||
val isJDK12OrLater = compilationJdkVersion >= 12
|
||||
return findFileByPath.children.filter { matchesRelease(it.name, release) }.flatMap {
|
||||
if (isJDK12OrLater)
|
||||
it.children.toList()
|
||||
else {
|
||||
listOf(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun listFoldersInCtSym() = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JAR_PROTOCOL)
|
||||
?.findFileByPath(ctSymFile!!.path + URLUtil.JAR_SEPARATOR)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user