diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ExecutionStrategyIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ExecutionStrategyIT.kt index ec44d708662..ee948eb9568 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ExecutionStrategyIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ExecutionStrategyIT.kt @@ -1,9 +1,23 @@ package org.jetbrains.kotlin.gradle import org.jetbrains.kotlin.gradle.util.getFileByName +import org.jetbrains.kotlin.gradle.util.modify import org.junit.Test -class ExecutionStrategyIT(): BaseGradleIT() { +class ExecutionStrategyJsIT : ExecutionStrategyIT() { + override fun setupProject(project: Project) { + project.setupWorkingDir() + val buildGradle = project.projectDir.getFileByName("build.gradle") + buildGradle.modify { it.replace("apply plugin: \"kotlin\"", "apply plugin: \"kotlin2js\"") + + "\ncompileKotlin2Js.kotlinOptions.outputFile = \"out.js\"" } + } + + override fun CompiledProject.checkOutput() { + assertFileExists("out.js") + } +} + +open class ExecutionStrategyIT : BaseGradleIT() { companion object { private const val GRADLE_VERSION = "2.10" } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt index 22e1ef90d1f..5aa6eb62a42 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt @@ -20,6 +20,7 @@ import net.rubygrapefruit.platform.Native import net.rubygrapefruit.platform.ProcessLauncher import org.gradle.api.Project import org.jetbrains.kotlin.cli.common.ExitCode +import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.config.Services @@ -85,6 +86,17 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil } } + fun runJsCompiler( + kotlinSources: List, + args: K2JSCompilerArguments, + messageCollector: MessageCollector, + outputItemsCollector: OutputItemsCollector, + kotlinCompilerJar: File + ): ExitCode { + val additionalArguments = kotlinSources.joinToString(separator = " ") { it.absolutePath } + return runCompiler(K2JS_COMPILER, args, additionalArguments, messageCollector, outputItemsCollector, GradleCompilerEnvironment(kotlinCompilerJar)) + } + override fun doRunCompiler(compilerClassName: String, argsArray: Array, environment: GradleCompilerEnvironment, messageCollector: MessageCollector, collector: OutputItemsCollector): ExitCode { val executionStrategy = System.getProperty(KOTLIN_COMPILER_EXECUTION_STRATEGY_PROPERTY) ?: DAEMON_EXECUTION_STRATEGY if (executionStrategy == DAEMON_EXECUTION_STRATEGY) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index 1dab5a43a2d..e2ec72b06a4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.gradle.tasks import org.codehaus.groovy.runtime.MethodClosure import org.gradle.api.GradleException +import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.logging.Logger import org.gradle.api.tasks.SourceSet @@ -81,6 +82,12 @@ abstract class AbstractKotlinCompile() : AbstractCo } var compilerJarFile: File? = null + protected val compilerJar: File + get() = compilerJarFile + ?: findKotlinCompilerJar(project) + ?: throw IllegalStateException("Could not find Kotlin Compiler jar. Please specify $name.compilerJarFile") + protected abstract fun findKotlinCompilerJar(project: Project): File? + internal var compilerCalled: Boolean = false // TODO: consider more reliable approach (see usage) internal var anyClassesCompiled: Boolean = false @@ -161,6 +168,9 @@ open class KotlinCompile : AbstractKotlinCompile(), Kotl // created only if kapt2 is active internal var sourceAnnotationsRegistry: SourceAnnotationsRegistry? = null + override fun findKotlinCompilerJar(project: Project): File? = + findKotlinJvmCompilerJar(project) + override fun populateCompilerArguments(): K2JVMCompilerArguments { val args = K2JVMCompilerArguments().apply { fillDefaultValues() } @@ -199,9 +209,6 @@ open class KotlinCompile : AbstractKotlinCompile(), Kotl args.classpathAsList = compileClasspath.toList() args.destinationAsFile = destinationDir val outputItemCollector = OutputItemsCollectorImpl() - val compilerJar = compilerJarFile - ?: findKotlinJvmCompilerJar(project) - ?: throw IllegalStateException("Could not find Kotlin Compiler jar. Please specify $name.compilerJarFile") if (!incremental) { anyClassesCompiled = true @@ -332,6 +339,9 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile(), outputs.file(MethodClosure(this, "getOutputFile")) } + override fun findKotlinCompilerJar(project: Project): File? = + findKotlinJsCompilerJar(project) + override fun populateCompilerArguments(): K2JSCompilerArguments { val args = K2JSCompilerArguments().apply { fillDefaultValues() } args.outputFile = outputFile @@ -367,20 +377,11 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile(), logger.kotlinDebug("compiling with args ${ArgumentUtils.convertArgumentsToStringList(args)}") - val gradleVersion = getGradleVersion() - val exitCode = if (gradleVersion == null || gradleVersion >= ParsedGradleVersion(3, 2)) { - // Gradle 3.2 bundles kotlin compiler - // This can cause problems with builtins resolution - // Compiling out of process as a workaround - val argsArray = ArgumentUtils.convertArgumentsToStringList(args).toTypedArray() - val compilerJar = compilerJarFile - ?: findKotlinJsCompilerJar(project) - ?: throw IllegalStateException("Could not find kotlin compiler jar. As a workaround specify $name.compilerJarFile") - compileOutOfProcess(argsArray, compiler.javaClass.canonicalName, compilerJar) - } - else { - compileInProcess(args) - } + val messageCollector = GradleMessageCollector(logger) + val outputItemCollector = OutputItemsCollectorImpl() + + val compilerRunner = GradleCompilerRunner(project) + val exitCode = compilerRunner.runJsCompiler(sourceRoots.kotlinSourceFiles, args, messageCollector, outputItemCollector, compilerJar) when (exitCode) { ExitCode.OK -> { @@ -391,12 +392,6 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile(), else -> throw GradleException("Unexpected exit code: $exitCode") } } - - private fun compileInProcess(args: K2JSCompilerArguments): ExitCode { - val messageCollector = GradleMessageCollector(logger) - val exitCode = compiler.exec(messageCollector, Services.EMPTY, args) - return exitCode - } } private fun Task.getGradleVersion(): ParsedGradleVersion? { @@ -408,35 +403,6 @@ private fun Task.getGradleVersion(): ParsedGradleVersion? { return result } -private fun compileOutOfProcess( - argsArray: Array, - compilerClassName: String, - compilerJar: File -): ExitCode { - try { - val javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java" - val builder = ProcessBuilder(javaBin, "-cp", compilerJar.absolutePath, compilerClassName, *argsArray) - val process = builder.start() - - // important to read inputStream, otherwise the process may hang on some systems - val readErrThread = thread { - process.errorStream!!.bufferedReader().forEachLine { - System.err.println(it) - } - } - process.inputStream!!.bufferedReader().forEachLine { - System.out.println(it) - } - readErrThread.join() - - val exitCode = process.waitFor() - if (exitCode == 0) return ExitCode.OK else return ExitCode.COMPILATION_ERROR - } - catch (e: Throwable) { - return ExitCode.INTERNAL_ERROR - } -} - internal class GradleMessageCollector(val logger: Logger) : MessageCollector { private var hasErrors = false