Introduce experimental -Xuse-javac compilation mode
In this mode, javac AST and Symbol files are used during Kotlin compilation instead of PSI / binary stuff. Later, they are reused for Java file compilation. javac in this mode is integrated into kotlinc.
This commit is contained in:
committed by
Mikhail Glukhikh
parent
c9a04fe1e2
commit
5eea3b6569
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException
|
||||
import org.jetbrains.kotlin.compiler.plugin.PluginCliOptionProcessingException
|
||||
import org.jetbrains.kotlin.compiler.plugin.cliPluginUsageString
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
|
||||
@@ -158,6 +159,10 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
val environment = createEnvironmentWithScriptingSupport(rootDisposable, configuration, arguments, messageCollector)
|
||||
?: return COMPILATION_ERROR
|
||||
|
||||
registerJavacIfNeeded(environment, arguments).let {
|
||||
if (!it) return COMPILATION_ERROR
|
||||
}
|
||||
|
||||
KotlinToJVMBytecodeCompiler.compileModules(environment, directory)
|
||||
}
|
||||
else if (arguments.script) {
|
||||
@@ -183,6 +188,10 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
val environment = createEnvironmentWithScriptingSupport(rootDisposable, configuration, arguments, messageCollector)
|
||||
?: return COMPILATION_ERROR
|
||||
|
||||
registerJavacIfNeeded(environment, arguments).let {
|
||||
if (!it) return COMPILATION_ERROR
|
||||
}
|
||||
|
||||
if (environment.getSourceFiles().isEmpty()) {
|
||||
if (arguments.version) {
|
||||
return OK
|
||||
@@ -192,6 +201,10 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
}
|
||||
|
||||
KotlinToJVMBytecodeCompiler.compileBunchOfSources(environment)
|
||||
|
||||
compileJavaFilesIfNeeded(environment, arguments).let {
|
||||
if (!it) return COMPILATION_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.reportPerf) {
|
||||
@@ -211,6 +224,23 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerJavacIfNeeded(environment: KotlinCoreEnvironment,
|
||||
arguments: K2JVMCompilerArguments): Boolean {
|
||||
if (arguments.useJavac) {
|
||||
environment.configuration.put(JVMConfigurationKeys.USE_JAVAC, true)
|
||||
return environment.registerJavac(arguments = arguments.javacArguments)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun compileJavaFilesIfNeeded(environment: KotlinCoreEnvironment,
|
||||
arguments: K2JVMCompilerArguments): Boolean {
|
||||
if (arguments.useJavac) {
|
||||
return JavacWrapper.getInstance(environment.project).use { it.compile() }
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun createEnvironmentWithScriptingSupport(rootDisposable: Disposable,
|
||||
configuration: CompilerConfiguration,
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.intellij.core.CoreApplicationEnvironment
|
||||
import com.intellij.core.CoreJavaFileManager
|
||||
import com.intellij.core.JavaCoreApplicationEnvironment
|
||||
import com.intellij.core.JavaCoreProjectEnvironment
|
||||
import com.intellij.ide.highlighter.JavaFileType
|
||||
import com.intellij.ide.plugins.PluginManagerCore
|
||||
import com.intellij.lang.MetaLanguage
|
||||
import com.intellij.lang.java.JavaParserDefinition
|
||||
@@ -70,10 +71,7 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
|
||||
import org.jetbrains.kotlin.cli.common.toBooleanLenient
|
||||
import org.jetbrains.kotlin.cli.jvm.JvmRuntimeVersionsConsistencyChecker
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmContentRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.config.*
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesDynamicCompoundIndex
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndex
|
||||
@@ -89,6 +87,7 @@ import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension
|
||||
import org.jetbrains.kotlin.extensions.PreprocessedVirtualFileFactoryExtension
|
||||
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.javac.JavacWrapperRegistrar
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
|
||||
import org.jetbrains.kotlin.load.kotlin.MetadataFinderFactory
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
|
||||
@@ -219,6 +218,28 @@ class KotlinCoreEnvironment private constructor(
|
||||
project.registerService(VirtualFileFinderFactory::class.java, finderFactory)
|
||||
}
|
||||
|
||||
private val VirtualFile.javaFiles: List<VirtualFile>
|
||||
get() = mutableListOf<VirtualFile>().apply {
|
||||
VfsUtilCore.processFilesRecursively(this@javaFiles) { file ->
|
||||
if (file.fileType == JavaFileType.INSTANCE) {
|
||||
add(file)
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
private val allJavaFiles: List<File>
|
||||
get() = configuration.javaSourceRoots
|
||||
.mapNotNull(this::findLocalDirectory)
|
||||
.flatMap { it.javaFiles }
|
||||
.map { File(it.canonicalPath) }
|
||||
|
||||
fun registerJavac(javaFiles: List<File> = allJavaFiles,
|
||||
kotlinFiles: List<KtFile> = sourceFiles,
|
||||
arguments: Array<String>? = null): Boolean {
|
||||
return JavacWrapperRegistrar.registerJavac(this, javaFiles, kotlinFiles, arguments)
|
||||
}
|
||||
|
||||
private val applicationEnvironment: CoreApplicationEnvironment
|
||||
get() = projectEnvironment.environment
|
||||
|
||||
@@ -327,6 +348,10 @@ class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun findLocalFile(path: String) = applicationEnvironment.localFileSystem.findFileByPath(path)
|
||||
|
||||
fun findJarFile(path: String) = applicationEnvironment.jarFileSystem.findFileByPath(path)
|
||||
|
||||
private fun findLocalDirectory(root: JvmContentRoot): VirtualFile? {
|
||||
val path = root.file
|
||||
val localFile = findLocalDirectory(path.absolutePath)
|
||||
|
||||
+18
-2
@@ -33,8 +33,7 @@ import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.OUTPUT
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
|
||||
import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAll
|
||||
@@ -52,6 +51,7 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.addKotlinSourceRoots
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
|
||||
import org.jetbrains.kotlin.modules.Module
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
@@ -164,6 +164,22 @@ object KotlinToJVMBytecodeCompiler {
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
writeOutput(state.configuration, state.factory, null)
|
||||
}
|
||||
|
||||
if (projectConfiguration.getBoolean(JVMConfigurationKeys.USE_JAVAC)) {
|
||||
val singleModule = chunk.singleOrNull()
|
||||
if (singleModule != null) {
|
||||
return JavacWrapper.getInstance(environment.project).use {
|
||||
it.compile(File(singleModule.getOutputDirectory()))
|
||||
}
|
||||
}
|
||||
else {
|
||||
projectConfiguration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).let {
|
||||
it.report(WARNING, "A chunk contains multiple modules (${chunk.joinToString { it.getModuleName() }}). -Xuse-javac option couldn't be used to compile java files")
|
||||
}
|
||||
JavacWrapper.getInstance(environment.project).close()
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
finally {
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.cli.jvm.config
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.ContentRoot
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.KotlinSourceRoot
|
||||
import java.io.File
|
||||
|
||||
data class JvmClasspathRoot(override val file: File): JvmContentRoot
|
||||
@@ -46,3 +47,10 @@ val CompilerConfiguration.jvmClasspathRoots: List<File>
|
||||
|
||||
@JvmOverloads fun CompilerConfiguration.addJavaSourceRoots(files: List<File>, packagePrefix: String? = null): Unit =
|
||||
files.forEach { addJavaSourceRoot(it, packagePrefix) }
|
||||
|
||||
val CompilerConfiguration.javaSourceRoots: Set<String>
|
||||
get() = get(JVMConfigurationKeys.CONTENT_ROOTS)
|
||||
?.mapNotNullTo(hashSetOf<String>()) {
|
||||
(it as? KotlinSourceRoot)?.path ?: (it as? JavaSourceRoot)?.file?.path
|
||||
}
|
||||
.orEmpty()
|
||||
Reference in New Issue
Block a user