diff --git a/src/main/kotlin/com/beust/kobalt/internal/JvmCompiler.kt b/src/main/kotlin/com/beust/kobalt/internal/JvmCompiler.kt new file mode 100644 index 00000000..0aad921d --- /dev/null +++ b/src/main/kotlin/com/beust/kobalt/internal/JvmCompiler.kt @@ -0,0 +1,51 @@ +package com.beust.kobalt.internal + +import com.beust.kobalt.api.KobaltContext +import com.beust.kobalt.api.Project +import com.beust.kobalt.maven.DependencyManager +import com.beust.kobalt.maven.IClasspathDependency +import com.google.inject.Inject + +class JvmCompiler @Inject constructor(val dependencyManager: DependencyManager) { + fun doCompile(project: Project?, context: KobaltContext?, action: ICompilerAction, info: CompilerActionInfo) + : TaskResult { + val allDependencies = arrayListOf() + allDependencies.addAll(info.dependencies) + allDependencies.addAll(calculateDependencies(project, context, info.dependencies)) + JvmCompilerPlugin.validateClasspath(allDependencies.map { it.jarFile.get().absolutePath }) + return action.compile(info.copy(dependencies = allDependencies)) + } + + /** + * @return the classpath for this project, including the IClasspathContributors. + */ + fun calculateDependencies(project: Project?, context: KobaltContext?, + vararg allDependencies: List): List { + var result = arrayListOf() + allDependencies.forEach { dependencies -> + result.addAll(dependencyManager.transitiveClosure(dependencies)) + } + if (project != null) { + result.addAll(runClasspathContributors(context, project)) + } + + return result + } + + private fun runClasspathContributors(context: KobaltContext?, project: Project) : + Collection { + val result = arrayListOf() + context?.classpathContributors?.forEach { + result.addAll(it.entriesFor(project)) + } + return result + } + +} + +data class CompilerActionInfo(val dependencies: List, + val sourceFiles: List, val outputDir: String, val compilerArgs: List) + +interface ICompilerAction { + fun compile(info: CompilerActionInfo): TaskResult +} \ No newline at end of file diff --git a/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt b/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt index d8d3f24f..3d378e7f 100644 --- a/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt @@ -10,7 +10,7 @@ import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.KobaltExecutors import com.beust.kobalt.misc.log import java.io.File -import java.util.ArrayList +import java.util.* import javax.inject.Inject import javax.inject.Singleton @@ -20,7 +20,8 @@ abstract class JvmCompilerPlugin @Inject constructor( open val files: KFiles, open val depFactory: DepFactory, open val dependencyManager: DependencyManager, - open val executors: KobaltExecutors) : BasePlugin() { + open val executors: KobaltExecutors, + open val jvmCompiler: JvmCompiler) : BasePlugin() { companion object { const val TASK_CLEAN = "clean" @@ -37,16 +38,6 @@ abstract class JvmCompilerPlugin @Inject constructor( } } } - - - private fun runClasspathContributors(context: KobaltContext?, project: Project) : - Collection { - val result = arrayListOf() - context!!.classpathContributors.forEach { - result.addAll(it.entriesFor(project)) - } - return result - } } /** @@ -63,21 +54,8 @@ abstract class JvmCompilerPlugin @Inject constructor( } /** - * @return the classpath for this project, including the IClasspathContributors. + * @return the test dependencies for this project, including the contributors. */ - fun calculateClasspath(project: Project?, vararg allDependencies: List): - List { - var result = arrayListOf() - allDependencies.forEach { dependencies -> - result.addAll(dependencyManager.transitiveClosure(dependencies)) - } - if (project != null) { - result.addAll(runClasspathContributors(context, project)) - } - - return result - } - protected fun testDependencies(project: Project) : List { val result = arrayListOf() result.add(FileDependency(makeOutputDir(project).absolutePath)) @@ -85,7 +63,7 @@ abstract class JvmCompilerPlugin @Inject constructor( with(project) { arrayListOf(compileDependencies, compileProvidedDependencies, testDependencies, testProvidedDependencies).forEach { - result.addAll(calculateClasspath(project, it)) + result.addAll(jvmCompiler.calculateDependencies(project, context!!, it)) } } return dependencyManager.reorderDependencies(result) @@ -145,7 +123,6 @@ abstract class JvmCompilerPlugin @Inject constructor( } } - class TestConfig(val project: Project) { fun args(vararg arg: String) { project.testArgs.addAll(arg) diff --git a/src/main/kotlin/com/beust/kobalt/kotlin/BuildFileCompiler.kt b/src/main/kotlin/com/beust/kobalt/kotlin/BuildFileCompiler.kt index f184884b..ba6a80df 100644 --- a/src/main/kotlin/com/beust/kobalt/kotlin/BuildFileCompiler.kt +++ b/src/main/kotlin/com/beust/kobalt/kotlin/BuildFileCompiler.kt @@ -7,9 +7,10 @@ import com.beust.kobalt.api.KobaltContext import com.beust.kobalt.api.Plugin import com.beust.kobalt.api.Project import com.beust.kobalt.api.annotation.Task -import com.beust.kobalt.internal.remote.KobaltServer import com.beust.kobalt.maven.KobaltException -import com.beust.kobalt.misc.* +import com.beust.kobalt.misc.KFiles +import com.beust.kobalt.misc.countChar +import com.beust.kobalt.misc.log import com.beust.kobalt.plugin.kotlin.kotlinCompilePrivate import com.google.inject.assistedinject.Assisted import rx.subjects.PublishSubject @@ -73,7 +74,8 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b return result } - private fun maybeCompileBuildFile(buildFile: BuildFile, buildScriptJarFile: File, pluginUrls: List) { + private fun maybeCompileBuildFile(buildFile: BuildFile, buildScriptJarFile: File, + pluginUrls: List) { log(2, "Running build file ${buildFile.name} jar: $buildScriptJarFile") if (buildFile.exists() && buildScriptJarFile.exists() @@ -87,7 +89,7 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b classpath(pluginUrls.map { it.file }) sourceFiles(listOf(buildFile.path.toFile().absolutePath)) output = buildScriptJarFile.absolutePath - }.compile() + }.compile(null /* no projects yet */) } } @@ -153,7 +155,7 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b classpath(files.kobaltJar) sourceFiles(buildFile.path.toFile().absolutePath) output = buildScriptJarFile.absolutePath - }.compile() + }.compile(null) } class BuildScriptInfo(val projects: List, val classLoader: ClassLoader) diff --git a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt index 00277eac..25b49ebe 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt @@ -6,6 +6,7 @@ import com.beust.kobalt.api.Kobalt import com.beust.kobalt.api.Project import com.beust.kobalt.api.annotation.Directive import com.beust.kobalt.api.annotation.Task +import com.beust.kobalt.internal.JvmCompiler import com.beust.kobalt.internal.JvmCompilerPlugin import com.beust.kobalt.internal.TaskResult import com.beust.kobalt.maven.DepFactory @@ -14,9 +15,6 @@ import com.beust.kobalt.maven.IClasspathDependency import com.beust.kobalt.maven.LocalRepo import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.KobaltExecutors -import com.beust.kobalt.misc.log -import com.beust.kobalt.plugin.kotlin.KotlinCompilerConfig -import com.beust.kobalt.plugin.kotlin.KotlinPlugin import java.io.File import java.nio.file.Paths import java.util.* @@ -30,8 +28,9 @@ public class JavaPlugin @Inject constructor( override val depFactory: DepFactory, override val dependencyManager: DependencyManager, override val executors: KobaltExecutors, - val javaCompiler: JavaCompiler) - : JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors) { + val javaCompiler: JavaCompiler, + override val jvmCompiler: JvmCompiler) + : JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler) { init { Kobalt.registerCompiler(JavaCompilerInfo()) @@ -77,7 +76,7 @@ public class JavaPlugin @Inject constructor( val sourceFiles = files.findRecursively(projectDir, project.sourceDirectories.map { File(it) }) { it: String -> it.endsWith(".java") } .map { File(projectDir, it).absolutePath } - val classpath = calculateClasspath(project, project.compileDependencies) + val classpath = jvmCompiler.calculateDependencies(project, context!!, project.compileDependencies) val args = arrayListOf( javadoc!!.absolutePath, "-classpath", classpath.map { it.jarFile.get().absolutePath }.joinToString(File.pathSeparator), @@ -105,7 +104,7 @@ public class JavaPlugin @Inject constructor( val sourceFiles = files.findRecursively(projectDir, project.sourceDirectories.map { File(it) }) { it: String -> it.endsWith(".java") } .map { File(projectDir, it).absolutePath } - val classpath = calculateClasspath(project, project.compileDependencies) + val classpath = jvmCompiler.calculateDependencies(project, context!!, project.compileDependencies) return compilePrivate(project, classpath, sourceFiles, buildDir) } diff --git a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt index 4ebbe6b9..b48e0810 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt @@ -1,8 +1,8 @@ package com.beust.kobalt.plugin.kotlin; import com.beust.kobalt.api.Kobalt -import com.beust.kobalt.internal.JvmCompilerPlugin -import com.beust.kobalt.internal.TaskResult +import com.beust.kobalt.api.Project +import com.beust.kobalt.internal.* import com.beust.kobalt.maven.* import com.beust.kobalt.misc.KobaltExecutors import com.beust.kobalt.misc.log @@ -22,8 +22,9 @@ class KotlinCompiler @Inject constructor(override val localRepo : LocalRepo, override val files: com.beust.kobalt.misc.KFiles, override val depFactory: DepFactory, override val dependencyManager: DependencyManager, - override val executors: KobaltExecutors) - : JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors) { + override val executors: KobaltExecutors, + override val jvmCompiler: JvmCompiler) + : JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler) { private val KOTLIN_VERSION = "1.0.0-beta-1038" override val name = "kotlin" @@ -35,30 +36,43 @@ class KotlinCompiler @Inject constructor(override val localRepo : LocalRepo, return result } - fun compile(compileDependencies: List, otherClasspath: List, + fun compile(project: Project?, compileDependencies: List, otherClasspath: List, source: List, output: String, args: List) : TaskResult { + val executor = executors.newExecutor("KotlinCompiler", 10) - val compilerDep = depFactory.create("org.jetbrains.kotlin:kotlin-compiler-embeddable:${KOTLIN_VERSION}", - executor) + val compilerDep = depFactory.create("org.jetbrains.kotlin:kotlin-compiler-embeddable:$KOTLIN_VERSION", executor) val deps = compilerDep.transitiveDependencies(executor) + + // Force a download of the compiler dependencies deps.forEach { it.jarFile.get() } + executor.shutdown() + val classpathList = arrayListOf( getKotlinCompilerJar("kotlin-stdlib"), getKotlinCompilerJar("kotlin-compiler-embeddable")) + .map { FileDependency(it) } - classpathList.addAll(otherClasspath) - classpathList.addAll(calculateClasspath(null, compileDependencies).map { it.id }) - - validateClasspath(classpathList) - - log(2, "Compiling ${source.size} files with classpath:\n " + classpathList.joinToString("\n ")) - CLICompiler.doMainNoExit(K2JVMCompiler(), arrayOf( - "-d", output, - "-classpath", classpathList.joinToString(File.pathSeparator), *source.toTypedArray(), - *args.toTypedArray())) - executor.shutdown() - return TaskResult() + val dependencies = arrayListOf() + .plus(compileDependencies) + .plus(classpathList) + .plus(otherClasspath.map { FileDependency(it)}) + val info = CompilerActionInfo(dependencies, source, output, args) + val compilerAction = object: ICompilerAction { + override fun compile(info: CompilerActionInfo): TaskResult { + log(1, "Compiling ${source.size} files") + val allArgs : Array = arrayOf( + "-d", info.outputDir, + "-classpath", info.dependencies.map {it.jarFile.get()}.joinToString(File.pathSeparator), + *(info.compilerArgs.toTypedArray()), + info.sourceFiles.joinToString(" ") + ) + log(2, "Calling kotlinc " + allArgs.joinToString(" ")) + CLICompiler.doMainNoExit(K2JVMCompiler(), allArgs) + return TaskResult() + } + } + return jvmCompiler.doCompile(project, context, compilerAction, info) } } @@ -79,8 +93,8 @@ class KConfiguration @Inject constructor(val compiler: KotlinCompiler){ fun compilerArgs(s: List) = args.addAll(s) - public fun compile() : TaskResult { - return compiler.compile(dependencies, classpath, source, output, args) + fun compile(project: Project?) : TaskResult { + return compiler.compile(project, dependencies, classpath, source, output, args) } } diff --git a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt index ac040d2b..c76c61dd 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt @@ -4,9 +4,13 @@ import com.beust.kobalt.api.Kobalt import com.beust.kobalt.api.Project import com.beust.kobalt.api.annotation.Directive import com.beust.kobalt.api.annotation.Task +import com.beust.kobalt.internal.JvmCompiler import com.beust.kobalt.internal.JvmCompilerPlugin import com.beust.kobalt.internal.TaskResult -import com.beust.kobalt.maven.* +import com.beust.kobalt.maven.DepFactory +import com.beust.kobalt.maven.DependencyManager +import com.beust.kobalt.maven.IClasspathDependency +import com.beust.kobalt.maven.LocalRepo import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.KobaltExecutors import com.beust.kobalt.misc.log @@ -20,8 +24,9 @@ class KotlinPlugin @Inject constructor( override val files: KFiles, override val depFactory: DepFactory, override val dependencyManager: DependencyManager, - override val executors: KobaltExecutors) - : JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors) { + override val executors: KobaltExecutors, + override val jvmCompiler: JvmCompiler) + : JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler) { init { Kobalt.registerCompiler(KotlinCompilerInfo()) @@ -41,7 +46,8 @@ class KotlinPlugin @Inject constructor( @Task(name = TASK_COMPILE, description = "Compile the project") fun taskCompile(project: Project): TaskResult { copyResources(project, JvmCompilerPlugin.SOURCE_SET_MAIN) - val classpath = calculateClasspath(project, project.compileDependencies, project.compileProvidedDependencies) + val classpath = jvmCompiler.calculateDependencies(project, context!!, project.compileDependencies, + project.compileProvidedDependencies) val projectDirectory = java.io.File(project.directory) val buildDirectory = File(projectDirectory, project.buildDirectory + File.separator + "classes") @@ -53,7 +59,7 @@ class KotlinPlugin @Inject constructor( File(projectDirectory, it).absolutePath } - compilePrivate(classpath, absoluteSourceFiles, buildDirectory.absolutePath) + compilePrivate(project, classpath, absoluteSourceFiles, buildDirectory.absolutePath) lp(project, "Compilation succeeded") return TaskResult() } @@ -71,7 +77,7 @@ class KotlinPlugin @Inject constructor( { it: String -> it.endsWith(".kt") } .map { File(projectDir, it).absolutePath } - compilePrivate(testDependencies(project), + compilePrivate(project, testDependencies(project), absoluteSourceFiles, makeOutputTestDir(project).absolutePath) @@ -79,7 +85,7 @@ class KotlinPlugin @Inject constructor( return TaskResult() } - private fun compilePrivate(cpList: List, sources: List, + private fun compilePrivate(project: Project, cpList: List, sources: List, outputDirectory: String): TaskResult { File(outputDirectory).mkdirs() @@ -90,7 +96,7 @@ class KotlinPlugin @Inject constructor( sourceFiles(sources) compilerArgs(compilerArgs) output = outputDirectory - }.compile() + }.compile(project) } }