1
0
Fork 0
mirror of https://github.com/ethauvin/kobalt.git synced 2025-04-26 16:28:12 -07:00

No more classes extend JvmCompilerPlugin.

This commit is contained in:
Cedric Beust 2016-02-04 21:44:51 +04:00
parent 02995ce6cb
commit 638d16588e
13 changed files with 148 additions and 143 deletions

View file

@ -24,6 +24,32 @@ open class Project(
@Directive open var packageName: String? = group,
val projectInfo: IProjectInfo) : IBuildConfig {
class ProjectExtra(project: Project) {
val suffixesFound = hashSetOf<String>()
init {
Kobalt.context?.let {
project.sourceDirectories.forEach { source ->
val sourceDir = File(KFiles.joinDir(project.directory, source))
KFiles.findRecursively(sourceDir, { file ->
val ind = file.lastIndexOf(".")
if (ind >= 0) {
suffixesFound.add(file.substring(ind + 1))
}
false
})
}
println("Suffixes: " + suffixesFound)
}
}
}
/**
* Initialized as soon as all the projects are parsed. This field caches a bunch of things we don't
* want to recalculate all the time, such as the list of suffixes found in this project.
*/
lateinit var projectExtra : ProjectExtra
val testConfigs = arrayListOf(TestConfig(this))
override var buildConfig : BuildConfig? = null //BuildConfig()
@ -38,24 +64,40 @@ open class Project(
return name.hashCode()
}
companion object {
val DEFAULT_SOURCE_DIRECTORIES = hashSetOf("src/main/java", "src/main/kotlin", "src/main/resources")
val DEFAULT_SOURCE_DIRECTORIES_TEST = hashSetOf("src/test/java", "src/test/kotlin")
}
//
// Directories
//
@Directive
fun sourceDirectories(init: Sources.() -> Unit) = Sources(this, sourceDirectories).apply { init() }
fun sourceDirectories(init: Sources.() -> Unit) : Sources {
return Sources(this, sourceDirectories).apply { init() }
}
var sourceDirectories : HashSet<String> = hashSetOf()
get() = if (field.isEmpty()) projectInfo.defaultSourceDirectories else field
private fun existing(dirs: Set<String>) = dirs.filter { File(directory, it).exists() }.toHashSet()
var sourceDirectories = hashSetOf<String>()
get() = existing(if (field.isEmpty()) DEFAULT_SOURCE_DIRECTORIES else field)
set(value) { field = value }
@Directive
fun sourceDirectoriesTest(init: Sources.() -> Unit) = Sources(this, sourceDirectoriesTest).apply { init() }
fun sourceDirectoriesTest(init: Sources.() -> Unit) : Sources {
return Sources(this, sourceDirectoriesTest).apply { init() }
}
var sourceDirectoriesTest : HashSet<String> = hashSetOf()
get() = if (field.isEmpty()) projectInfo.defaultTestDirectories else field
var sourceDirectoriesTest = hashSetOf<String>()
get() = existing(if (field.isEmpty()) DEFAULT_SOURCE_DIRECTORIES_TEST else field)
set(value) { field = value }
init {
sourceDirectories = hashSetOf()
sourceDirectoriesTest = hashSetOf()
}
//
// Dependencies
//

View file

@ -0,0 +1,26 @@
package com.beust.kobalt.internal
import com.beust.kobalt.api.*
/**
* Base class for JVM language plug-ins.
*/
abstract class BaseJvmPlugin<T>: ConfigPlugin<T>(), IProjectContributor, ICompilerFlagContributor {
override fun apply(project: Project, context: KobaltContext) {
super.apply(project, context)
project.projectProperties.put(JvmCompilerPlugin.DEPENDENT_PROJECTS, projects())
}
private val allProjects = arrayListOf<ProjectDescription>()
fun addDependentProjects(project: Project, dependents: List<Project>) {
project.projectInfo.dependsOn.addAll(dependents)
with(ProjectDescription(project, dependents)) {
allProjects.add(this)
}
}
// IProjectContributor
override fun projects() = allProjects
}

View file

@ -21,12 +21,11 @@ import javax.inject.Inject
import javax.inject.Singleton
/**
* Base classes for plug-ins that compile files on the JVM. This base class requires the bare minimum
* contributors (source files, projects and tasks). Subclasses can add more as they see fit (e.g. test
* source directory, etc...).
* This plug-in takes care of compilation: it declares a bunch of tasks ("compile", "compileTest") and
* and picks up all the compiler contributors in order to run them whenever a compilation is requested.
*/
@Singleton
abstract class JvmCompilerPlugin @Inject constructor(
open class JvmCompilerPlugin @Inject constructor(
open val localRepo: LocalRepo,
open val files: KFiles,
open val depFactory: DepFactory,
@ -53,6 +52,10 @@ abstract class JvmCompilerPlugin @Inject constructor(
const val DOCS_DIRECTORY = "docs/javadoc"
}
override val name: String = "JvmCompiler"
override fun accept(project: Project) = true
/**
* Log with a project.
*/
@ -132,12 +135,6 @@ abstract class JvmCompilerPlugin @Inject constructor(
}
}
open fun toClassFile(sourceFile: String) = sourceFile + ".class"
fun addCompilerArgs(project: Project, vararg args: String) {
project.projectProperties.put(COMPILER_ARGS, arrayListOf(*args))
}
@IncrementalTask(name = JvmCompilerPlugin.TASK_COMPILE, description = "Compile the project")
fun taskCompile(project: Project): IncrementalTaskInfo {
val inputChecksum = Md5.toMd5Directories(project.sourceDirectories.map {
@ -152,7 +149,11 @@ abstract class JvmCompilerPlugin @Inject constructor(
)
}
private fun doTaskCompile(project: Project): TaskResult {
private fun doTaskCompile(project: Project) = doTaskCompile(project, isTest = false)
private fun doTaskCompileTest(project: Project) = doTaskCompile(project, isTest = true)
private fun doTaskCompile(project: Project, isTest: Boolean): TaskResult {
// Set up the source files now that we have the variant
sourceDirectories.addAll(context.variant.sourceDirectories(project, context))
@ -160,9 +161,8 @@ abstract class JvmCompilerPlugin @Inject constructor(
if (sourceDirectory != null) {
sourceDirectories.add(sourceDirectory)
}
// val info = createCompilerActionInfo(project, context, isTest = false)
// val compiler = ActorUtils.selectAffinityActor(project, context, context.pluginInfo.compilerContributors)
val results = arrayListOf<TaskResult>()
val compilers = ActorUtils.selectAffinityActors(project, context, context.pluginInfo.compilerContributors)
var failedResult: TaskResult? = null
@ -170,8 +170,7 @@ abstract class JvmCompilerPlugin @Inject constructor(
throw KobaltException("Couldn't find any compiler for project ${project.name}")
} else {
compilers.forEach { compiler ->
val info = createCompilerActionInfo(project, context, isTest = false,
sourceSuffixes = compiler.sourceSuffixes)
val info = createCompilerActionInfo(project, context, isTest, sourceSuffixes = compiler.sourceSuffixes)
val thisResult = compiler.compile(project, context, info)
results.add(thisResult)
if (! thisResult.success && failedResult == null) {
@ -185,13 +184,6 @@ abstract class JvmCompilerPlugin @Inject constructor(
val allProjects = arrayListOf<ProjectDescription>()
fun addDependentProjects(project: Project, dependents: List<Project>) {
project.projectInfo.dependsOn.addAll(dependents)
with(ProjectDescription(project, dependents)) {
allProjects.add(this)
}
}
override fun projects() : List<ProjectDescription> {
return allProjects
}
@ -278,7 +270,7 @@ abstract class JvmCompilerPlugin @Inject constructor(
// Finally, alter the info with the compiler interceptors before returning it
val initialActionInfo = CompilerActionInfo(projectDirectory.path, classpath, sourceFiles + extraSourceFiles,
buildDirectory, emptyList())
buildDirectory, emptyList() /* the flags will be provided by flag contributors */)
val result = context.pluginInfo.compilerInterceptors.fold(initialActionInfo, { ai, interceptor ->
interceptor.intercept(project, context, ai)
})
@ -306,6 +298,6 @@ abstract class JvmCompilerPlugin @Inject constructor(
)
}
abstract protected fun doTaskCompileTest(project: Project): TaskResult
open val compiler: ICompilerContributor? = null
}

View file

@ -11,9 +11,6 @@ import java.util.*
* Data that is useful for projects to have but should not be specified in the DSL.
*/
interface IProjectInfo {
val defaultSourceDirectories: HashSet<String>
val defaultTestDirectories: HashSet<String>
/**
* If at least one build config was found either on the project or the variant, this function
* will be used to generate the BuildConfig file with the correct language.

View file

@ -55,6 +55,9 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
// Find all the projects in the build file, possibly compiling them
//
val allProjects = findProjects(context)
allProjects.forEach {
it.projectExtra = Project.ProjectExtra(it)
}
plugins.applyPlugins(context, allProjects)
return allProjects

View file

@ -5,8 +5,8 @@ import com.beust.kobalt.plugin.java.JavaProjectInfo
import com.google.inject.Inject
public class JavaBuildGenerator @Inject constructor (val projectInfo: JavaProjectInfo) : BuildGenerator() {
override val defaultSourceDirectories = projectInfo.defaultSourceDirectories
override val defaultTestDirectories = projectInfo.defaultTestDirectories
override val defaultSourceDirectories = hashSetOf("src/main/java")
override val defaultTestDirectories = hashSetOf("src/test/java")
override val directive = "javaProject"
override val name = "java"
override val fileMatch = { f: String -> f.endsWith(".java") }

View file

@ -5,8 +5,8 @@ import com.beust.kobalt.plugin.kotlin.KotlinProjectInfo
import com.google.inject.Inject
public class KotlinBuildGenerator @Inject constructor (val projectInfo: KotlinProjectInfo) : BuildGenerator() {
override val defaultSourceDirectories = projectInfo.defaultSourceDirectories
override val defaultTestDirectories = projectInfo.defaultTestDirectories
override val defaultSourceDirectories = hashSetOf("src/main/kotlin")
override val defaultTestDirectories = hashSetOf("src/test/kotlin")
override val directive = "kotlinProject"
override val name = "kotlin"
override val fileMatch = { f: String -> f.endsWith(".kt") }

View file

@ -52,6 +52,7 @@ class JavaCompiler @Inject constructor(val jvmCompiler: JvmCompiler) {
command = "javac " + allArgs.joinToString(" ") + " " + info.sourceFiles.joinToString(" ")
log(2, "Launching\n$command")
log(1, " Java compiling ${info.sourceFiles.size} files")
val result = task.call()
errorMessage = dc.diagnostics.joinToString("\n")
result
@ -71,8 +72,8 @@ class JavaCompiler @Inject constructor(val jvmCompiler: JvmCompiler) {
val pb = ProcessBuilder(allArgs)
pb.inheritIO()
val line = allArgs.joinToString(" ")
log(1, " Compiling ${info.sourceFiles.size} files")
log(2, " Compiling $line")
log(1, " Java compiling ${info.sourceFiles.size} files")
log(2, " Java compiling $line")
command = allArgs.joinToString(" ") + " " + info.sourceFiles.joinToString(" ")
val process = pb.start()

View file

@ -3,37 +3,22 @@ package com.beust.kobalt.plugin.java
import com.beust.kobalt.TaskResult
import com.beust.kobalt.api.*
import com.beust.kobalt.api.annotation.Directive
import com.beust.kobalt.internal.JvmCompiler
import com.beust.kobalt.internal.JvmCompilerPlugin
import com.beust.kobalt.maven.DepFactory
import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.maven.LocalRepo
import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.KobaltExecutors
import com.beust.kobalt.internal.BaseJvmPlugin
import com.beust.kobalt.misc.warn
import java.io.File
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class JavaPlugin @Inject constructor(
override val localRepo: LocalRepo,
override val files: KFiles,
override val depFactory: DepFactory,
override val dependencyManager: DependencyManager,
override val executors: KobaltExecutors,
val javaCompiler: JavaCompiler,
override val jvmCompiler: JvmCompiler,
override val taskContributor : TaskContributor)
: JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler, taskContributor),
ICompilerContributor, IDocContributor, ITestSourceDirectoryContributor {
class JavaPlugin @Inject constructor(val javaCompiler: JavaCompiler)
: BaseJvmPlugin<JavaConfig>(), IDocContributor, ICompilerContributor, ITestSourceDirectoryContributor {
companion object {
const val PLUGIN_NAME = "Java"
}
override val name = PLUGIN_NAME
override fun accept(project: Project) = project.sourceDirectories.any { it.contains("java") }
override fun accept(project: Project) = project.projectExtra.suffixesFound.contains("java")
// IDocContributor
override fun affinity(project: Project, context: KobaltContext) =
@ -42,7 +27,7 @@ class JavaPlugin @Inject constructor(
override fun generateDoc(project: Project, context: KobaltContext, info: CompilerActionInfo) : TaskResult {
val result =
if (info.sourceFiles.size > 0) {
javaCompiler.javadoc(project, context, info.copy(compilerArgs = compilerArgsFor(project)))
javaCompiler.javadoc(project, context, info)
} else {
warn("Couldn't find any source files to run Javadoc on")
TaskResult()
@ -50,13 +35,9 @@ class JavaPlugin @Inject constructor(
return result
}
override fun doTaskCompileTest(project: Project): TaskResult {
copyResources(project, JvmCompilerPlugin.SOURCE_SET_TEST)
val compilerActionInfo = createCompilerActionInfo(project, context, isTest = true,
sourceSuffixes = sourceSuffixes)
val result = javaCompiler.compile(project, context, compilerActionInfo)
return result
}
// ICompilerFlagsContributor
override fun flagsFor(project: Project, context: KobaltContext, currentFlags: List<String>)
= configurationFor(project)?.compilerArgs ?: listOf<String>()
// ICompilerContributor
override val sourceSuffixes = listOf("java")
@ -64,7 +45,7 @@ class JavaPlugin @Inject constructor(
override fun compile(project: Project, context: KobaltContext, info: CompilerActionInfo) : TaskResult {
val result =
if (info.sourceFiles.size > 0) {
javaCompiler.compile(project, context, info.copy(compilerArgs = compilerArgsFor(project)))
javaCompiler.compile(project, context, info)
} else {
warn("Couldn't find any source files to compile")
TaskResult()
@ -75,24 +56,25 @@ class JavaPlugin @Inject constructor(
// ITestSourceDirectoryContributor
override fun testSourceDirectoriesFor(project: Project, context: KobaltContext)
= project.sourceDirectoriesTest.map { File(it) }.toList()
}
@Directive
public fun javaProject(vararg projects: Project, init: JavaProject.() -> Unit): JavaProject {
return JavaProject().apply {
init()
(Kobalt.findPlugin(JavaPlugin.PLUGIN_NAME) as JvmCompilerPlugin).addDependentProjects(this, projects.toList())
(Kobalt.findPlugin(JavaPlugin.PLUGIN_NAME) as JavaPlugin).addDependentProjects(this, projects.toList())
}
}
class JavaCompilerConfig(val project: Project) {
fun args(vararg options: String) {
(Kobalt.findPlugin(JavaPlugin.PLUGIN_NAME) as JvmCompilerPlugin).addCompilerArgs(project, *options)
}
class JavaConfig(val project: Project) {
val compilerArgs = arrayListOf<String>()
fun args(vararg options: String) = compilerArgs.addAll(options)
}
@Directive
fun Project.javaCompiler(init: JavaCompilerConfig.() -> Unit) = let {
JavaCompilerConfig(it).init()
fun Project.javaCompiler(init: JavaConfig.() -> Unit) = let {
val config = JavaConfig(it)
config.init()
(Kobalt.findPlugin(JavaPlugin.PLUGIN_NAME) as JavaPlugin).addConfiguration(this, config)
}

View file

@ -10,9 +10,6 @@ import com.google.inject.Singleton
@Singleton
class JavaProjectInfo : BaseProjectInfo() {
override val defaultSourceDirectories = hashSetOf("src/main/java", "src/main/resources")
override val defaultTestDirectories = hashSetOf("src/test/java", "src/test/resources")
override fun generate(field: BuildConfigField) = with(field) {
" public static final $type $name = $value;"
}

View file

@ -38,7 +38,7 @@ class KotlinCompiler @Inject constructor(
val compilerAction = object: ICompilerAction {
override fun compile(projectName: String?, info: CompilerActionInfo): TaskResult {
if (info.sourceFiles.size > 1) {
log(1, " Compiling ${info.sourceFiles.size} files")
log(1, " Kotlin compiling ${info.sourceFiles.size} files")
}
val cp = compilerFirst(info.dependencies.map {it.jarFile.get()})
val outputDir = if (info.directory != null) {
@ -152,7 +152,7 @@ class KConfiguration @Inject constructor(val compiler: KotlinCompiler){
fun compilerArgs(s: List<String>) = args.addAll(s)
fun compile(project: Project? = null, context: KobaltContext? = null) : TaskResult {
return compiler.compile(project, context, dependencies, classpath, source, output, args + "-no-stdlib")
return compiler.compile(project, context, dependencies, classpath, source, output, args /* + "-no-stdlib" */)
}
}

View file

@ -3,43 +3,27 @@ package com.beust.kobalt.plugin.kotlin
import com.beust.kobalt.TaskResult
import com.beust.kobalt.api.*
import com.beust.kobalt.api.annotation.Directive
import com.beust.kobalt.internal.JvmCompiler
import com.beust.kobalt.internal.JvmCompilerPlugin
import com.beust.kobalt.maven.DepFactory
import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.maven.LocalRepo
import com.beust.kobalt.internal.BaseJvmPlugin
import com.beust.kobalt.maven.dependency.FileDependency
import com.beust.kobalt.maven.dependency.MavenDependency
import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.KobaltExecutors
import com.beust.kobalt.misc.log
import com.beust.kobalt.misc.warn
import java.io.File
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class KotlinPlugin @Inject constructor(
override val localRepo: LocalRepo,
override val files: KFiles,
override val depFactory: DepFactory,
override val dependencyManager: DependencyManager,
override val executors: KobaltExecutors,
override val jvmCompiler: JvmCompiler,
override val taskContributor : TaskContributor)
: JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler, taskContributor),
IClasspathContributor, ICompilerContributor, IDocContributor {
class KotlinPlugin @Inject constructor(val executors: KobaltExecutors)
: BaseJvmPlugin<KotlinConfig>(), IDocContributor, IClasspathContributor, ICompilerContributor {
companion object {
const val PLUGIN_NAME = "Kotlin"
}
override fun apply(project: Project, context: KobaltContext) {
super.apply(project, context)
}
override val name = PLUGIN_NAME
override fun accept(project: Project) = project.sourceDirectories.any { it.contains("kotlin") }
override fun accept(project: Project) = project.projectExtra.suffixesFound.contains("kt")
// IDocContributor
override fun affinity(project: Project, context: KobaltContext) =
@ -49,6 +33,10 @@ class KotlinPlugin @Inject constructor(
return TaskResult()
}
// ICompilerFlagsContributor
override fun flagsFor(project: Project, context: KobaltContext, currentFlags: List<String>)
= configurationFor(project)?.compilerArgs ?: listOf<String>()
// override fun generateDoc(project: Project, context: KobaltContext, info: CompilerActionInfo) : TaskResult {
// val configs = dokkaConfigurations[project.name]
// val classpath = context.dependencyManager.calculateDependencies(project, context)
@ -80,35 +68,12 @@ class KotlinPlugin @Inject constructor(
// return TaskResult(success)
// }
override protected fun doTaskCompileTest(project: Project) : TaskResult {
copyResources(project, JvmCompilerPlugin.SOURCE_SET_TEST)
val projectDir = File(project.directory)
val sourceFiles = files.findRecursively(projectDir, project.sourceDirectoriesTest.map { File(it) })
{ file: String -> sourceSuffixes.any { file.endsWith(it) } }
.map { File(projectDir, it).absolutePath }
val result =
if (sourceFiles.size > 0) {
compilePrivate(project, dependencyManager.testDependencies(project, context),
sourceFiles,
KFiles.makeOutputTestDir(project))
} else {
warn("Couldn't find any source test files")
TaskResult()
}
lp(project, "Compilation of tests succeeded")
return result
}
private fun compilePrivate(project: Project, cpList: List<IClasspathDependency>, sources: List<String>,
outputDirectory: File): TaskResult {
outputDirectory: File, compilerArgs: List<String>): TaskResult {
return kotlinCompilePrivate {
classpath(cpList.map { it.jarFile.get().absolutePath })
sourceFiles(sources)
compilerArgs(compilerArgsFor(project))
compilerArgs(compilerArgs)
output = outputDirectory
}.compile(project, context)
}
@ -120,10 +85,9 @@ class KotlinPlugin @Inject constructor(
return result
}
// interface IClasspathContributor
override fun entriesFor(project: Project?): List<IClasspathDependency> =
if (project == null || project is KotlinProject) {
if (project == null || accept(project)) {
// All Kotlin projects automatically get the Kotlin runtime added to their class path
listOf(getKotlinCompilerJar("kotlin-stdlib"), getKotlinCompilerJar("kotlin-runtime"))
.map { FileDependency(it) }
@ -138,7 +102,7 @@ class KotlinPlugin @Inject constructor(
override fun compile(project: Project, context: KobaltContext, info: CompilerActionInfo) : TaskResult {
val result =
if (info.sourceFiles.size > 0) {
compilePrivate(project, info.dependencies, info.sourceFiles, info.outputDir)
compilePrivate(project, info.dependencies, info.sourceFiles, info.outputDir, info.compilerArgs)
} else {
warn("Couldn't find any source files")
TaskResult()
@ -154,7 +118,10 @@ class KotlinPlugin @Inject constructor(
// dokkaConfigurations.put(project.name, dokkaConfig)
// }
override fun toClassFile(sourceFile: String) = sourceFile + "Kt.class"
protected fun lp(project: Project, s: String) {
log(2, "${project.name}: $s")
}
}
/**
@ -164,19 +131,20 @@ class KotlinPlugin @Inject constructor(
fun kotlinProject(vararg projects: Project, init: KotlinProject.() -> Unit): KotlinProject {
return KotlinProject().apply {
init()
(Kobalt.findPlugin(KotlinPlugin.PLUGIN_NAME) as JvmCompilerPlugin).addDependentProjects(this, projects.toList())
(Kobalt.findPlugin(KotlinPlugin.PLUGIN_NAME) as KotlinPlugin).addDependentProjects(this, projects.toList())
}
}
class KotlinCompilerConfig(val project: Project) {
fun args(vararg options: String) {
(Kobalt.findPlugin(KotlinPlugin.PLUGIN_NAME) as JvmCompilerPlugin).addCompilerArgs(project, *options)
}
class KotlinConfig(val project: Project) {
val compilerArgs = arrayListOf<String>()
fun args(vararg options: String) = compilerArgs.addAll(options)
}
@Directive
fun Project.kotlinCompiler(init: KotlinCompilerConfig.() -> Unit) = let {
KotlinCompilerConfig(it).init()
fun Project.kotlinCompiler(init: KotlinConfig.() -> Unit) = let {
val config = KotlinConfig(it)
config.init()
(Kobalt.findPlugin(KotlinPlugin.PLUGIN_NAME) as KotlinPlugin).addConfiguration(this, config)
}
//class SourceLinkMapItem {

View file

@ -10,9 +10,6 @@ import com.google.inject.Singleton
@Singleton
class KotlinProjectInfo : BaseProjectInfo() {
override val defaultSourceDirectories = hashSetOf("src/main/kotlin", "src/main/resources")
override val defaultTestDirectories = hashSetOf("src/test/kotlin", "src/test/resources")
override fun generate(field: BuildConfigField) = with(field) {
" val $name : $type = $value"
}