diff --git a/jps/jps-plugin/jps-plugin.iml b/jps/jps-plugin/jps-plugin.iml
index b7f14f215a5..21a11f39ee9 100644
--- a/jps/jps-plugin/jps-plugin.iml
+++ b/jps/jps-plugin/jps-plugin.iml
@@ -10,6 +10,7 @@
+
diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerEnvironment.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerEnvironment.kt
deleted file mode 100644
index 119b0357974..00000000000
--- a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerEnvironment.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2010-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.compilerRunner
-
-import org.jetbrains.kotlin.cli.common.messages.MessageCollector
-import org.jetbrains.kotlin.config.Services
-import org.jetbrains.kotlin.preloading.ClassCondition
-import org.jetbrains.kotlin.utils.KotlinPaths
-import org.jetbrains.kotlin.utils.PathUtil
-
-import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation.Companion.NO_LOCATION
-import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
-
-class CompilerEnvironment private constructor(
- val kotlinPaths: KotlinPaths,
- val classesToLoadByParent: ClassCondition,
- val services: Services
-) {
-
- fun success(): Boolean {
- return kotlinPaths.homePath.exists()
- }
-
- fun reportErrorsTo(messageCollector: MessageCollector) {
- if (!kotlinPaths.homePath.exists()) {
- messageCollector.report(ERROR, "Cannot find kotlinc home: " + kotlinPaths.homePath + ". Make sure plugin is properly installed, " +
- "or specify " + PathUtil.JPS_KOTLIN_HOME_PROPERTY + " system property", NO_LOCATION)
- }
- }
-
- companion object {
- fun getEnvironmentFor(
- kotlinPaths: KotlinPaths,
- classesToLoadByParent: ClassCondition,
- compilerServices: Services
- ): CompilerEnvironment {
- return CompilerEnvironment(kotlinPaths, classesToLoadByParent, compilerServices)
- }
- }
-}
diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerOutputParser.java b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerOutputParser.java
deleted file mode 100644
index beaebcab7f1..00000000000
--- a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerOutputParser.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright 2010-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.compilerRunner;
-
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.containers.Stack;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-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.OutputMessageUtil;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.Map;
-
-import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation.NO_LOCATION;
-import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*;
-import static org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil.reportException;
-
-public class CompilerOutputParser {
- public static void parseCompilerMessagesFromReader(MessageCollector messageCollector, final Reader reader, OutputItemsCollector collector) {
- // Sometimes the compiler doesn't output valid XML.
- // Example: error in command line arguments passed to the compiler.
- // The compiler will print the usage and the SAX parser will break.
- // In this case, we want to read everything from this stream and report it as an IDE error.
- final StringBuilder stringBuilder = new StringBuilder();
- Reader wrappingReader = new Reader() {
- @Override
- public int read(@NotNull char[] cbuf, int off, int len) throws IOException {
- int read = reader.read(cbuf, off, len);
- stringBuilder.append(cbuf, off, len);
- return read;
- }
-
- @Override
- public void close() throws IOException {
- // Do nothing:
- // If the SAX parser sees a syntax error, it throws an exception
- // and calls close() on the reader.
- // We prevent hte reader from being closed here, and close it later,
- // when all the text is read from it
- }
- };
- try {
- SAXParserFactory factory = SAXParserFactory.newInstance();
- SAXParser parser = factory.newSAXParser();
- parser.parse(new InputSource(wrappingReader), new CompilerOutputSAXHandler(messageCollector, collector));
- }
- catch (Throwable e) {
- // Load all the text into the stringBuilder
- try {
- // This will not close the reader (see the wrapper above)
- FileUtil.loadTextAndClose(wrappingReader);
- }
- catch (IOException ioException) {
- reportException(messageCollector, ioException);
- }
- String message = stringBuilder.toString();
- reportException(messageCollector, new IllegalStateException(message, e));
- messageCollector.report(ERROR, message, NO_LOCATION);
- }
- finally {
- try {
- reader.close();
- }
- catch (IOException e) {
- reportException(messageCollector, e);
- }
- }
- }
-
- private static class CompilerOutputSAXHandler extends DefaultHandler {
- private static final Map CATEGORIES = new ContainerUtil.ImmutableMapBuilder()
- .put("error", ERROR)
- .put("warning", WARNING)
- .put("logging", LOGGING)
- .put("output", OUTPUT)
- .put("exception", EXCEPTION)
- .put("info", INFO)
- .put("messages", INFO) // Root XML element
- .build();
-
- private final MessageCollector messageCollector;
- private final OutputItemsCollector collector;
-
- private final StringBuilder message = new StringBuilder();
- private final Stack tags = new Stack();
- private String path;
- private int line;
- private int column;
-
- public CompilerOutputSAXHandler(MessageCollector messageCollector, OutputItemsCollector collector) {
- this.messageCollector = messageCollector;
- this.collector = collector;
- }
-
- @Override
- public void startElement(@NotNull String uri, @NotNull String localName, @NotNull String qName, @NotNull Attributes attributes)
- throws SAXException {
- tags.push(qName);
-
- message.setLength(0);
-
- path = attributes.getValue("path");
- line = safeParseInt(attributes.getValue("line"), -1);
- column = safeParseInt(attributes.getValue("column"), -1);
- }
-
- @Override
- public void characters(char[] ch, int start, int length) throws SAXException {
- if (tags.size() == 1) {
- // We're directly inside the root tag:
- String message = new String(ch, start, length);
- if (!message.trim().isEmpty()) {
- messageCollector.report(ERROR, "Unhandled compiler output: " + message, NO_LOCATION);
- }
- }
- else {
- message.append(ch, start, length);
- }
- }
-
- @Override
- public void endElement(String uri, @NotNull String localName, @NotNull String qName) throws SAXException {
- if (tags.size() == 1) {
- // We're directly inside the root tag:
- return;
- }
- String qNameLowerCase = qName.toLowerCase();
- CompilerMessageSeverity category = CATEGORIES.get(qNameLowerCase);
- if (category == null) {
- messageCollector.report(ERROR, "Unknown compiler message tag: " + qName, NO_LOCATION);
- category = INFO;
- }
- String text = message.toString();
-
- if (category == OUTPUT) {
- reportToCollector(text);
- }
- else {
- messageCollector.report(category, text, CompilerMessageLocation.create(path, line, column, null));
- }
- tags.pop();
- }
-
- private void reportToCollector(String text) {
- OutputMessageUtil.Output output = OutputMessageUtil.parseOutputMessage(text);
- if (output != null) {
- collector.add(output.sourceFiles, output.outputFile);
- }
- }
-
- private static int safeParseInt(@Nullable String value, int defaultValue) {
- if (value == null) {
- return defaultValue;
- }
- try {
- return Integer.parseInt(value.trim());
- }
- catch (NumberFormatException e) {
- return defaultValue;
- }
- }
- }
-}
diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt
deleted file mode 100644
index 011550c9845..00000000000
--- a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright 2010-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.compilerRunner
-
-import org.jetbrains.jps.api.GlobalOptions
-import org.jetbrains.kotlin.cli.common.ExitCode
-import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY
-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.arguments.mergeBeans
-import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
-import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
-import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
-import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO
-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.daemon.client.CompilationServices
-import org.jetbrains.kotlin.daemon.client.DaemonReportMessage
-import org.jetbrains.kotlin.daemon.client.DaemonReportingTargets
-import org.jetbrains.kotlin.daemon.client.KotlinCompilerClient
-import org.jetbrains.kotlin.daemon.common.*
-import org.jetbrains.kotlin.jps.build.KotlinBuilder
-import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
-import org.jetbrains.kotlin.progress.CompilationCanceledStatus
-import java.io.*
-import java.util.*
-import java.util.concurrent.TimeUnit
-
-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()
-
- fun runK2JvmCompiler(
- commonArguments: CommonCompilerArguments,
- k2jvmArguments: K2JVMCompilerArguments,
- compilerSettings: CompilerSettings,
- messageCollector: MessageCollector,
- environment: CompilerEnvironment,
- moduleFile: File,
- collector: OutputItemsCollector) {
- val arguments = mergeBeans(commonArguments, k2jvmArguments)
- setupK2JvmArguments(moduleFile, arguments)
-
- runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment)
- }
-
- fun runK2JsCompiler(
- commonArguments: CommonCompilerArguments,
- k2jsArguments: K2JSCompilerArguments,
- compilerSettings: CompilerSettings,
- messageCollector: MessageCollector,
- environment: CompilerEnvironment,
- collector: OutputItemsCollector,
- sourceFiles: Collection,
- libraryFiles: List,
- outputFile: File) {
- val arguments = mergeBeans(commonArguments, k2jsArguments)
- setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments)
-
- runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment)
- }
-
- 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 == exitCode) {
- reportInternalCompilerError(messageCollector)
- }
- }
-
- private fun reportInternalCompilerError(messageCollector: MessageCollector) {
- messageCollector.report(ERROR, "Compiler terminated with internal error", CompilerMessageLocation.NO_LOCATION)
- }
-
- private fun runCompiler(
- compilerClassName: String,
- arguments: CommonCompilerArguments,
- additionalArguments: String,
- messageCollector: MessageCollector,
- collector: OutputItemsCollector,
- environment: CompilerEnvironment) {
- try {
- messageCollector.report(INFO, "Using kotlin-home = " + environment.kotlinPaths.homePath, CompilerMessageLocation.NO_LOCATION)
-
- val argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments)
- argumentsList.addAll(additionalArguments.split(" "))
-
- val argsArray = argumentsList.toTypedArray()
-
- if (!tryCompileWithDaemon(compilerClassName, argsArray, environment, messageCollector, collector)) {
- // otherwise fallback to in-process
- KotlinBuilder.LOG.info("Compile in-process")
-
- val stream = ByteArrayOutputStream()
- val out = PrintStream(stream)
-
- // the property should be set at least for parallel builds to avoid parallel building problems (racing between destroying and using environment)
- // unfortunately it cannot be currently set by default globally, because it breaks many tests
- // since there is no reliable way so far to detect running under tests, switching it on only for parallel builds
- if (System.getProperty(GlobalOptions.COMPILE_PARALLEL_OPTION, "false").toBoolean())
- System.setProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY, "true")
-
- 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))
- }
- }
- catch (e: Throwable) {
- MessageCollectorUtil.reportException(messageCollector, e)
- reportInternalCompilerError(messageCollector)
- }
-
- }
-
- internal class DaemonConnection(val daemon: CompileService?, val sessionId: Int = CompileService.NO_SESSION)
-
- internal object getDaemonConnection {
- private @Volatile var connection: DaemonConnection? = null
-
- @Synchronized operator fun invoke(environment: CompilerEnvironment, messageCollector: MessageCollector): DaemonConnection {
- if (connection == null) {
- val libPath = CompilerRunnerUtil.getLibPath(environment.kotlinPaths, messageCollector)
- val compilerId = CompilerId.makeCompilerId(File(libPath, "kotlin-compiler.jar"))
- val daemonOptions = configureDaemonOptions()
- val daemonJVMOptions = configureDaemonJVMOptions(inheritMemoryLimits = true, inheritAdditionalProperties = true)
-
- val daemonReportMessages = ArrayList()
-
- val profiler = if (daemonOptions.reportPerf) WallAndThreadAndMemoryTotalProfiler(withGC = false) else DummyProfiler()
-
- profiler.withMeasure(null) {
- val daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, DaemonReportingTargets(null, daemonReportMessages), true, true)
- connection = DaemonConnection(daemon, daemon?.leaseCompileSession(makeAutodeletingFlagFile("compiler-jps-session").absolutePath)?.get() ?: CompileService.NO_SESSION)
- }
-
- for (msg in daemonReportMessages) {
- messageCollector.report(CompilerMessageSeverity.INFO,
- (if (msg.category == DaemonReportCategory.EXCEPTION && connection?.daemon == null) "Falling back to compilation without daemon due to error: " else "") + msg.message,
- CompilerMessageLocation.NO_LOCATION)
- }
-
- reportTotalAndThreadPerf("Daemon connect", daemonOptions, messageCollector, profiler)
- }
- return connection!!
- }
- }
-
- private fun tryCompileWithDaemon(compilerClassName: String,
- argsArray: Array,
- environment: CompilerEnvironment,
- messageCollector: MessageCollector,
- collector: OutputItemsCollector,
- retryOnConnectionError: Boolean = true): Boolean {
-
- if (isDaemonEnabled()) {
-
- KotlinBuilder.LOG.debug("Try to connect to daemon")
- val connection = getDaemonConnection(environment, messageCollector)
-
- if (connection.daemon != null) {
- KotlinBuilder.LOG.info("Connected to daemon")
-
- val compilerOut = ByteArrayOutputStream()
- val daemonOut = ByteArrayOutputStream()
-
- val services = CompilationServices(
- incrementalCompilationComponents = environment.services.get(IncrementalCompilationComponents::class.java),
- compilationCanceledStatus = environment.services.get(CompilationCanceledStatus::class.java))
-
- val targetPlatform = when (compilerClassName) {
- K2JVM_COMPILER -> CompileService.TargetPlatform.JVM
- K2JS_COMPILER -> CompileService.TargetPlatform.JS
- else -> throw IllegalArgumentException("Unknown compiler type $compilerClassName")
- }
-
- fun retryOrFalse(e: Exception): Boolean {
- if (retryOnConnectionError) {
- KotlinBuilder.LOG.debug("retrying once on daemon connection error: ${e.message}")
- return tryCompileWithDaemon(compilerClassName, argsArray, environment, messageCollector, collector, retryOnConnectionError = false)
- }
- KotlinBuilder.LOG.info("daemon connection error: ${e.message}")
- return false
- }
-
- val res: Int = try {
- KotlinCompilerClient.incrementalCompile(connection.daemon, connection.sessionId, targetPlatform, argsArray, services, compilerOut, daemonOut)
- }
- catch (e: java.rmi.ConnectException) {
- return retryOrFalse(e)
- }
- catch (e: java.rmi.UnmarshalException) {
- return retryOrFalse(e)
- }
-
- processCompilerOutput(messageCollector, collector, compilerOut, res.toString())
- BufferedReader(StringReader(daemonOut.toString())).forEachLine {
- messageCollector.report(CompilerMessageSeverity.INFO, it, CompilerMessageLocation.NO_LOCATION)
- }
- return true
- }
-
- KotlinBuilder.LOG.info("Daemon not found")
- }
- return false
- }
-
- private fun reportTotalAndThreadPerf(message: String, daemonOptions: DaemonOptions, messageCollector: MessageCollector, profiler: Profiler) {
- if (daemonOptions.reportPerf) {
- fun Long.ms() = TimeUnit.NANOSECONDS.toMillis(this)
- val counters = profiler.getTotalCounters()
- messageCollector.report(INFO,
- "PERF: $message ${counters.time.ms()} ms, thread ${counters.threadTime.ms()}",
- CompilerMessageLocation.NO_LOCATION)
- }
- }
-
- private fun getReturnCodeFromObject(rc: Any?): String {
- when {
- rc == null -> return INTERNAL_ERROR
- ExitCode::class.java.name == rc.javaClass.name -> return rc.toString()
- else -> throw IllegalStateException("Unexpected return: " + rc)
- }
- }
-
- private fun setupK2JvmArguments(moduleFile: File, settings: K2JVMCompilerArguments) {
- with(settings) {
- module = moduleFile.absolutePath
- noStdlib = true
- noReflect = true
- noJdk = true
- }
- }
-
- private fun setupK2JsArguments( _outputFile: File, sourceFiles: Collection, _libraryFiles: List, settings: K2JSCompilerArguments) {
- with(settings) {
- noStdlib = true
- freeArgs = sourceFiles.map { it.path }
- outputFile = _outputFile.path
- metaInfo = true
- libraryFiles = _libraryFiles.toTypedArray()
- }
- }
-}