diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt index 3710979bd86..65dd3ccc23f 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt @@ -14,261 +14,247 @@ * limitations under the License. */ -package org.jetbrains.kotlin.compilerRunner; +package org.jetbrains.kotlin.compilerRunner -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.ArrayUtil; -import com.intellij.util.Function; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.xmlb.XmlSerializerUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.cli.common.ExitCode; -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments; -import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments; -import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments; -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation; -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity; -import org.jetbrains.kotlin.cli.common.messages.MessageCollector; -import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil; -import org.jetbrains.kotlin.config.CompilerSettings; -import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache; -import org.jetbrains.kotlin.modules.TargetId; -import org.jetbrains.kotlin.rmi.*; -import org.jetbrains.kotlin.rmi.kotlinr.DaemonReportCategory; -import org.jetbrains.kotlin.rmi.kotlinr.DaemonReportMessage; -import org.jetbrains.kotlin.rmi.kotlinr.DaemonReportingTargets; -import org.jetbrains.kotlin.rmi.kotlinr.KotlinCompilerClient; -import org.jetbrains.kotlin.utils.UtilsPackage; +import com.intellij.openapi.util.text.StringUtil +import com.intellij.util.ArrayUtil +import com.intellij.util.Function +import com.intellij.util.containers.ContainerUtil +import com.intellij.util.xmlb.XmlSerializerUtil +import org.jetbrains.kotlin.cli.common.ExitCode +import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil +import org.jetbrains.kotlin.config.CompilerSettings +import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache +import org.jetbrains.kotlin.modules.TargetId +import org.jetbrains.kotlin.rmi.* +import org.jetbrains.kotlin.rmi.kotlinr.DaemonReportCategory +import org.jetbrains.kotlin.rmi.kotlinr.DaemonReportMessage +import org.jetbrains.kotlin.rmi.kotlinr.DaemonReportingTargets +import org.jetbrains.kotlin.rmi.kotlinr.KotlinCompilerClient +import org.jetbrains.kotlin.utils.* -import java.io.*; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.io.* +import java.lang.reflect.Field +import java.lang.reflect.Modifier +import java.util.ArrayList -import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation.NO_LOCATION; -import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR; -import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO; +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO -public class KotlinCompilerRunner { - private static final String K2JVM_COMPILER = "org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"; - private static final String K2JS_COMPILER = "org.jetbrains.kotlin.cli.js.K2JSCompiler"; - private static final String INTERNAL_ERROR = ExitCode.INTERNAL_ERROR.toString(); +public object KotlinCompilerRunner { + private val K2JVM_COMPILER = "org.jetbrains.kotlin.cli.jvm.K2JVMCompiler" + private val K2JS_COMPILER = "org.jetbrains.kotlin.cli.js.K2JSCompiler" + private val INTERNAL_ERROR = ExitCode.INTERNAL_ERROR.toString() - public static void runK2JvmCompiler( - CommonCompilerArguments commonArguments, - K2JVMCompilerArguments k2jvmArguments, - CompilerSettings compilerSettings, - MessageCollector messageCollector, - CompilerEnvironment environment, - Map incrementalCaches, - File moduleFile, - OutputItemsCollector collector - ) { - K2JVMCompilerArguments arguments = mergeBeans(commonArguments, k2jvmArguments); - setupK2JvmArguments(moduleFile, arguments); + public fun runK2JvmCompiler( + commonArguments: CommonCompilerArguments, + k2jvmArguments: K2JVMCompilerArguments, + compilerSettings: CompilerSettings, + messageCollector: MessageCollector, + environment: CompilerEnvironment, + incrementalCaches: Map?, + moduleFile: File, + collector: OutputItemsCollector) { + val arguments = mergeBeans(commonArguments, k2jvmArguments) + setupK2JvmArguments(moduleFile, arguments) - runCompiler(K2JVM_COMPILER, arguments, compilerSettings.getAdditionalArguments(), messageCollector, collector, environment, - incrementalCaches); + runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment, + incrementalCaches) } - public static void runK2JsCompiler( - @NotNull CommonCompilerArguments commonArguments, - @NotNull K2JSCompilerArguments k2jsArguments, - @NotNull CompilerSettings compilerSettings, - @NotNull MessageCollector messageCollector, - @NotNull CompilerEnvironment environment, - Map incrementalCaches, - @NotNull OutputItemsCollector collector, - @NotNull Collection sourceFiles, - @NotNull List libraryFiles, - @NotNull File outputFile - ) { - K2JSCompilerArguments arguments = mergeBeans(commonArguments, k2jsArguments); - setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments); + public fun runK2JsCompiler( + commonArguments: CommonCompilerArguments, + k2jsArguments: K2JSCompilerArguments, + compilerSettings: CompilerSettings, + messageCollector: MessageCollector, + environment: CompilerEnvironment, + incrementalCaches: Map?, + collector: OutputItemsCollector, + sourceFiles: Collection, + libraryFiles: List, + outputFile: File) { + val arguments = mergeBeans(commonArguments, k2jsArguments) + setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments) - runCompiler(K2JS_COMPILER, arguments, compilerSettings.getAdditionalArguments(), messageCollector, collector, environment, - incrementalCaches); + runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment, + incrementalCaches) } - private static void ProcessCompilerOutput( - MessageCollector messageCollector, - OutputItemsCollector collector, - ByteArrayOutputStream stream, - String exitCode - ) { - BufferedReader reader = new BufferedReader(new StringReader(stream.toString())); - CompilerOutputParser.parseCompilerMessagesFromReader(messageCollector, reader, collector); + private fun ProcessCompilerOutput( + messageCollector: MessageCollector, + collector: OutputItemsCollector, + stream: ByteArrayOutputStream, + exitCode: String) { + val reader = BufferedReader(StringReader(stream.toString())) + CompilerOutputParser.parseCompilerMessagesFromReader(messageCollector, reader, collector) - if (INTERNAL_ERROR.equals(exitCode)) { - reportInternalCompilerError(messageCollector); + if (INTERNAL_ERROR == exitCode) { + reportInternalCompilerError(messageCollector) } } - private static void reportInternalCompilerError(MessageCollector messageCollector) { - messageCollector.report(ERROR, "Compiler terminated with internal error", NO_LOCATION); + private fun reportInternalCompilerError(messageCollector: MessageCollector) { + messageCollector.report(ERROR, "Compiler terminated with internal error", CompilerMessageLocation.NO_LOCATION) } - private static void runCompiler( - String compilerClassName, - CommonCompilerArguments arguments, - String additionalArguments, - MessageCollector messageCollector, - OutputItemsCollector collector, - CompilerEnvironment environment, - Map incrementalCaches - ) { + private fun runCompiler( + compilerClassName: String, + arguments: CommonCompilerArguments, + additionalArguments: String, + messageCollector: MessageCollector, + collector: OutputItemsCollector, + environment: CompilerEnvironment, + incrementalCaches: Map?) { try { - messageCollector.report(INFO, "Using kotlin-home = " + environment.getKotlinPaths().getHomePath(), NO_LOCATION); + messageCollector.report(INFO, "Using kotlin-home = " + environment.kotlinPaths.homePath, CompilerMessageLocation.NO_LOCATION) - List argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments); - argumentsList.addAll(StringUtil.split(additionalArguments, " ")); + val argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments) + argumentsList.addAll(StringUtil.split(additionalArguments, " ")) - String[] argsArray = ArrayUtil.toStringArray(argumentsList); + val argsArray = ArrayUtil.toStringArray(argumentsList) if (!tryCompileWithDaemon(messageCollector, collector, environment, incrementalCaches, argsArray)) { // otherwise fallback to in-process - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - PrintStream out = new PrintStream(stream); + val stream = ByteArrayOutputStream() + val out = PrintStream(stream) - Object rc = CompilerRunnerUtil.invokeExecMethod( compilerClassName, argsArray, environment, messageCollector, out); + val rc = CompilerRunnerUtil.invokeExecMethod(compilerClassName, argsArray, environment, messageCollector, out) // exec() returns an ExitCode object, class of which is loaded with a different class loader, // so we take it's contents through reflection - ProcessCompilerOutput(messageCollector, collector, stream, getReturnCodeFromObject(rc)); + ProcessCompilerOutput(messageCollector, collector, stream, getReturnCodeFromObject(rc)) } } - catch (Throwable e) { - MessageCollectorUtil.reportException(messageCollector, e); - reportInternalCompilerError(messageCollector); + catch (e: Throwable) { + MessageCollectorUtil.reportException(messageCollector, e) + reportInternalCompilerError(messageCollector) } + } - private static boolean tryCompileWithDaemon( - MessageCollector messageCollector, - OutputItemsCollector collector, - CompilerEnvironment environment, - Map incrementalCaches, - String[] argsArray - ) throws IOException { - if (incrementalCaches != null && RmiPackage.isDaemonEnabled()) { - File libPath = CompilerRunnerUtil.getLibPath(environment.getKotlinPaths(), messageCollector); + private fun tryCompileWithDaemon( + messageCollector: MessageCollector, + collector: OutputItemsCollector, + environment: CompilerEnvironment, + incrementalCaches: Map?, + argsArray: Array): Boolean { + if (incrementalCaches != null && isDaemonEnabled()) { + val libPath = CompilerRunnerUtil.getLibPath(environment.kotlinPaths, messageCollector) // TODO: it may be a good idea to cache the compilerId, since making it means calculating digest over jar(s) and if \\ // the lifetime of JPS process is small anyway, we can neglect the probability of changed compiler - CompilerId compilerId = CompilerId.makeCompilerId(new File(libPath, "kotlin-compiler.jar")); - DaemonOptions daemonOptions = RmiPackage.configureDaemonOptions(); - DaemonJVMOptions daemonJVMOptions = RmiPackage.configureDaemonJVMOptions(true); + val compilerId = CompilerId.makeCompilerId(File(libPath, "kotlin-compiler.jar")) + val daemonOptions = configureDaemonOptions() + val daemonJVMOptions = configureDaemonJVMOptions(true) - ArrayList daemonReportMessages = new ArrayList(); + val daemonReportMessages = ArrayList() - CompileService daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, new DaemonReportingTargets(null, daemonReportMessages), true, true); + val daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, DaemonReportingTargets(null, daemonReportMessages), true, true) - for (DaemonReportMessage msg: daemonReportMessages) { - if (msg.getCategory() == DaemonReportCategory.EXCEPTION && daemon == null) { + for (msg in daemonReportMessages) { + if (msg.category === DaemonReportCategory.EXCEPTION && daemon == null) { messageCollector.report(CompilerMessageSeverity.INFO, - "Falling back to compilation without daemon due to error: " + msg.getMessage(), - CompilerMessageLocation.NO_LOCATION); + "Falling back to compilation without daemon due to error: " + msg.message, + CompilerMessageLocation.NO_LOCATION) } else { - messageCollector.report(CompilerMessageSeverity.INFO, msg.getMessage(), CompilerMessageLocation.NO_LOCATION); + messageCollector.report(CompilerMessageSeverity.INFO, msg.message, CompilerMessageLocation.NO_LOCATION) } } if (daemon != null) { - ByteArrayOutputStream compilerOut = new ByteArrayOutputStream(); - ByteArrayOutputStream daemonOut = new ByteArrayOutputStream(); + val compilerOut = ByteArrayOutputStream() + val daemonOut = ByteArrayOutputStream() - Integer res = KotlinCompilerClient.incrementalCompile(daemon, argsArray, incrementalCaches, compilerOut, daemonOut); + val res = KotlinCompilerClient.incrementalCompile(daemon, argsArray, incrementalCaches, compilerOut, daemonOut) - ProcessCompilerOutput(messageCollector, collector, compilerOut, res.toString()); - BufferedReader reader = new BufferedReader(new StringReader(daemonOut.toString())); - String line = null; - while ((line = reader.readLine()) != null) { - messageCollector.report(CompilerMessageSeverity.INFO, line, CompilerMessageLocation.NO_LOCATION); + ProcessCompilerOutput(messageCollector, collector, compilerOut, res.toString()) + BufferedReader(StringReader(daemonOut.toString())).forEachLine { + messageCollector.report(CompilerMessageSeverity.INFO, it, CompilerMessageLocation.NO_LOCATION) } - return true; + return true } } - return false; + return false } - @NotNull - private static String getReturnCodeFromObject(@Nullable Object rc) throws Exception { + private fun getReturnCodeFromObject(rc: Any?): String { if (rc == null) { - return INTERNAL_ERROR; + return INTERNAL_ERROR } - else if (ExitCode.class.getName().equals(rc.getClass().getName())) { - return rc.toString(); + else if (ExitCode::class.java.name == rc.javaClass.name) { + return rc.toString() } else { - throw new IllegalStateException("Unexpected return: " + rc); + throw IllegalStateException("Unexpected return: " + rc) } } - private static T mergeBeans(CommonCompilerArguments from, T to) { + private fun mergeBeans(from: CommonCompilerArguments, to: T): T { // TODO: rewrite when updated version of com.intellij.util.xmlb is available on TeamCity try { - T copy = XmlSerializerUtil.createCopy(to); + val copy = XmlSerializerUtil.createCopy(to) - List fromFields = collectFieldsToCopy(from.getClass()); - for (Field fromField : fromFields) { - Field toField = copy.getClass().getField(fromField.getName()); - toField.set(copy, fromField.get(from)); + val fromFields = collectFieldsToCopy(from.javaClass) + for (fromField in fromFields) { + val toField = copy.javaClass.getField(fromField.name) + toField.set(copy, fromField.get(from)) } - return copy; + return copy } - catch (NoSuchFieldException e) { - throw UtilsPackage.rethrow(e); + catch (e: NoSuchFieldException) { + throw rethrow(e) } - catch (IllegalAccessException e) { - throw UtilsPackage.rethrow(e); + catch (e: IllegalAccessException) { + throw rethrow(e) } + } - private static List collectFieldsToCopy(Class clazz) { - List fromFields = new ArrayList(); + private fun collectFieldsToCopy(clazz: Class<*>): List { + val fromFields = ArrayList() - Class currentClass = clazz; - do { - for (Field field : currentClass.getDeclaredFields()) { - int modifiers = field.getModifiers(); + var currentClass: Class<*>? = clazz + while (currentClass != null) { + for (field in currentClass.declaredFields) { + val modifiers = field.modifiers if (!Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)) { - fromFields.add(field); + fromFields.add(field) } } + currentClass = currentClass.superclass } - while ((currentClass = currentClass.getSuperclass()) != null); - return fromFields; + return fromFields } - private static void setupK2JvmArguments(File moduleFile, K2JVMCompilerArguments settings) { - settings.module = moduleFile.getAbsolutePath(); - settings.noStdlib = true; - settings.noJdkAnnotations = true; - settings.noJdk = true; + private fun setupK2JvmArguments(moduleFile: File, settings: K2JVMCompilerArguments) { + settings.module = moduleFile.absolutePath + settings.noStdlib = true + settings.noJdkAnnotations = true + settings.noJdk = true } - private static void setupK2JsArguments( - @NotNull File outputFile, - @NotNull Collection sourceFiles, - @NotNull List libraryFiles, - @NotNull K2JSCompilerArguments settings - ) { - settings.noStdlib = true; - settings.freeArgs = ContainerUtil.map(sourceFiles, new Function() { - @Override - public String fun(File file) { - return file.getPath(); + private fun setupK2JsArguments( + outputFile: File, + sourceFiles: Collection, + libraryFiles: List, + settings: K2JSCompilerArguments) { + settings.noStdlib = true + settings.freeArgs = ContainerUtil.map(sourceFiles, object : Function { + override fun `fun`(file: File): String { + return file.path } - }); - settings.outputFile = outputFile.getPath(); - settings.metaInfo = true; - settings.libraryFiles = ArrayUtil.toStringArray(libraryFiles); + }) + settings.outputFile = outputFile.path + settings.metaInfo = true + settings.libraryFiles = ArrayUtil.toStringArray(libraryFiles) } } diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt index 3c10754f873..81a96f10aa0 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt @@ -47,8 +47,7 @@ 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.compilerRunner.CompilerEnvironment -import org.jetbrains.kotlin.compilerRunner.KotlinCompilerRunner.runK2JsCompiler -import org.jetbrains.kotlin.compilerRunner.KotlinCompilerRunner.runK2JvmCompiler +import org.jetbrains.kotlin.compilerRunner.KotlinCompilerRunner import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl import org.jetbrains.kotlin.config.CompilerRunnerConstants import org.jetbrains.kotlin.config.CompilerRunnerConstants.INTERNAL_ERROR_PREFIX @@ -520,7 +519,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR val compilerSettings = JpsKotlinCompilerSettings.getCompilerSettings(project) val k2JsArguments = JpsKotlinCompilerSettings.getK2JsCompilerArguments(project) - runK2JsCompiler(commonArguments, k2JsArguments, compilerSettings, messageCollector, environment, incrementalCaches, outputItemCollector, sourceFiles, libraryFiles, outputFile) + KotlinCompilerRunner.runK2JsCompiler(commonArguments, k2JsArguments, compilerSettings, messageCollector, environment, incrementalCaches, outputItemCollector, sourceFiles, libraryFiles, outputFile) return outputItemCollector } @@ -587,7 +586,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR + (if (totalRemovedFiles == 0) "" else " ($totalRemovedFiles removed files)") + " in " + filesToCompile.keySet().map { it.getPresentableName() }.join()) - runK2JvmCompiler(commonArguments, k2JvmArguments, compilerSettings, messageCollector, environment, incrementalCaches, moduleFile, outputItemCollector) + KotlinCompilerRunner.runK2JvmCompiler(commonArguments, k2JvmArguments, compilerSettings, messageCollector, environment, incrementalCaches, moduleFile, outputItemCollector) moduleFile.delete() return outputItemCollector