diff --git a/kobalt/src/Build.kt b/kobalt/src/Build.kt index 31aeb0e8..730b2bb9 100644 --- a/kobalt/src/Build.kt +++ b/kobalt/src/Build.kt @@ -12,7 +12,8 @@ import com.beust.kobalt.plugin.java.javaProject import com.beust.kobalt.plugin.kotlin.kotlinCompiler import com.beust.kobalt.plugin.kotlin.kotlinProject import com.beust.kobalt.plugin.packaging.assemble -import com.beust.kobalt.plugin.publish.* +import com.beust.kobalt.plugin.publish.github +import com.beust.kobalt.plugin.publish.jcenter import java.io.File import java.nio.file.Files import java.nio.file.Paths @@ -27,6 +28,15 @@ val wrapper = javaProject { args("-source", "1.7", "-target", "1.7") } + dependencies { + compile(file(homeDir("java/java-apt-example/processor/kobaltBuild/libs/processor-0.1.jar"))) +// apt(file(homeDir("java/java-apt-example/processor/kobaltBuild/libs/processor-0.1.jar"))) + } + +// apt { +// outputDir = "generated/sources/apt" +// } + assemble { jar { name = projectName + ".jar" diff --git a/modules/wrapper/src/main/java/com/beust/kobalt/wrapper/Main.java b/modules/wrapper/src/main/java/com/beust/kobalt/wrapper/Main.java index 89d1d418..22097591 100644 --- a/modules/wrapper/src/main/java/com/beust/kobalt/wrapper/Main.java +++ b/modules/wrapper/src/main/java/com/beust/kobalt/wrapper/Main.java @@ -9,6 +9,7 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; +//@com.beust.apt.processor.Version("1.3") public class Main { public static void main(String[] argv) throws IOException, InterruptedException { new Main().installAndLaunchMain(argv); diff --git a/src/main/kotlin/com/beust/kobalt/api/ICompilerFlagContributor.kt b/src/main/kotlin/com/beust/kobalt/api/ICompilerFlagContributor.kt new file mode 100644 index 00000000..896ed3e2 --- /dev/null +++ b/src/main/kotlin/com/beust/kobalt/api/ICompilerFlagContributor.kt @@ -0,0 +1,8 @@ +package com.beust.kobalt.api + +/** + * Plugins that add compiler flags. + */ +interface ICompilerFlagContributor : IContributor { + fun flagsFor(project: Project): List +} diff --git a/src/main/kotlin/com/beust/kobalt/internal/JvmCompiler.kt b/src/main/kotlin/com/beust/kobalt/internal/JvmCompiler.kt index 7ffd4bda..5c7d3a6a 100644 --- a/src/main/kotlin/com/beust/kobalt/internal/JvmCompiler.kt +++ b/src/main/kotlin/com/beust/kobalt/internal/JvmCompiler.kt @@ -8,6 +8,7 @@ import com.beust.kobalt.maven.IClasspathDependency import com.beust.kobalt.maven.KobaltException import com.google.inject.Inject import java.io.File +import java.util.* /** * Abstract the compilation process by running an ICompilerAction parameterized by a CompilerActionInfo. @@ -16,16 +17,27 @@ import java.io.File class JvmCompiler @Inject constructor(val dependencyManager: DependencyManager) { /** - * Create a final, enriched CompilerActionInfo from the contributors and the transitive dependencies and + * Take the given CompilerActionInfo and enrich it with all the applicable contributors and * then pass it to the ICompilerAction. */ fun doCompile(project: Project?, context: KobaltContext?, action: ICompilerAction, info: CompilerActionInfo) : TaskResult { - val allDependencies = info.dependencies + calculateDependencies(project, context, info.dependencies) + // Dependencies + val allDependencies = info.dependencies + calculateDependencies(project, context!!, info.dependencies) + + // Plugins that add flags to the compiler + val addedFlags = ArrayList(info.compilerArgs) + + if (project != null) { + context.pluginInfo.compilerFlagContributors.flatMap { + it.flagsFor(project) + } + } else { + emptyList() + } validateClasspath(allDependencies.map { it.jarFile.get().absolutePath }) - return action.compile(info.copy(dependencies = allDependencies)) + return action.compile(info.copy(dependencies = allDependencies, compilerArgs = addedFlags)) } private fun validateClasspath(cp: List) { @@ -39,7 +51,7 @@ class JvmCompiler @Inject constructor(val dependencyManager: DependencyManager) /** * @return the classpath for this project, including the IClasspathContributors. */ - fun calculateDependencies(project: Project?, context: KobaltContext?, + fun calculateDependencies(project: Project?, context: KobaltContext, vararg allDependencies: List): List { var result = arrayListOf() allDependencies.forEach { dependencies -> @@ -50,10 +62,10 @@ class JvmCompiler @Inject constructor(val dependencyManager: DependencyManager) return result } - private fun runClasspathContributors(project: Project?, context: KobaltContext?) : + private fun runClasspathContributors(project: Project?, context: KobaltContext) : Collection { val result = hashSetOf() - context!!.pluginInfo.classpathContributors.forEach { it: IClasspathContributor -> + context.pluginInfo.classpathContributors.forEach { it: IClasspathContributor -> result.addAll(it.entriesFor(project)) } return result diff --git a/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt b/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt index bdb39d46..bb1d727f 100644 --- a/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt +++ b/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt @@ -39,16 +39,19 @@ class KobaltPluginXml { var factoryClassName: String? = null @XmlElement(name = "classpath-contributors") @JvmField - var classpathClassName: ClassNameXml? = null + var classpathContributors: ClassNameXml? = null @XmlElement(name = "project-contributors") @JvmField - var projectClassName: ClassNameXml? = null + var projectContributors: ClassNameXml? = null @XmlElement(name = "init-contributors") @JvmField - var initClassName: ClassNameXml? = null + var initContributors: ClassNameXml? = null @XmlElement(name = "repo-contributors") @JvmField - var repoClassName: ClassNameXml? = null + var repoContributors: ClassNameXml? = null + + @XmlElement(name = "compiler-flag-contributors") @JvmField + var compilerFlagContributors: ClassNameXml? = null } class ContributorXml { @@ -72,12 +75,11 @@ class PluginInfo(val xml: KobaltPluginXml, val classLoader: ClassLoader?) { val classpathContributors = arrayListOf() val initContributors = arrayListOf() val repoContributors = arrayListOf() + val compilerFlagContributors = arrayListOf() // Future contributors: - // compilerArgs // source files // compilers - // repos companion object { val PLUGIN_XML = "META-INF/plugin.xml" // Plugins.PLUGIN_XML) @@ -123,18 +125,21 @@ class PluginInfo(val xml: KobaltPluginXml, val classLoader: ClassLoader?) { xml.plugins?.className?.forEach { plugins.add(factory.instanceOf(forName(it)) as IPlugin) } - xml.classpathClassName?.className?.forEach { + xml.classpathContributors?.className?.forEach { classpathContributors.add(factory.instanceOf(forName(it)) as IClasspathContributor) } - xml.projectClassName?.className?.forEach { + xml.projectContributors?.className?.forEach { projectContributors.add(factory.instanceOf(forName(it)) as IProjectContributor) } - xml.initClassName?.className?.forEach { + xml.initContributors?.className?.forEach { initContributors.add(factory.instanceOf(forName(it)) as IInitContributor) } - xml.repoClassName?.className?.forEach { + xml.repoContributors?.className?.forEach { repoContributors.add(factory.instanceOf(forName(it)) as IRepoContributor) } + xml.compilerFlagContributors?.className?.forEach { + compilerFlagContributors.add(factory.instanceOf(forName(it)) as ICompilerFlagContributor) + } } fun addPluginInfo(pluginInfo: PluginInfo) { diff --git a/src/main/kotlin/com/beust/kobalt/plugin/apt/AptPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/apt/AptPlugin.kt index ebf67659..37bd5831 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/apt/AptPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/apt/AptPlugin.kt @@ -1,37 +1,73 @@ package com.beust.kobalt.plugin.apt -import com.beust.kobalt.api.BasePlugin -import com.beust.kobalt.api.Dependencies -import com.beust.kobalt.api.Kobalt -import com.beust.kobalt.api.Project +import com.beust.kobalt.api.* import com.beust.kobalt.api.annotation.Directive -import com.beust.kobalt.api.annotation.Task -import com.beust.kobalt.internal.TaskResult +import com.beust.kobalt.maven.DepFactory +import com.beust.kobalt.misc.KFiles +import com.beust.kobalt.misc.KobaltExecutors import com.beust.kobalt.misc.log +import com.google.inject.Inject import javax.inject.Singleton +/** + * The AptPlugin has two components: + * 1) A new apt directive inside a dependency{} block (similar to compile()) that declares where + * the annotation process is found + * 2) An apt{} configuration on Project that lets the user configure how the annotation is performed + * (outputDir, etc...). + */ @Singleton -public class AptPlugin : BasePlugin() { +public class AptPlugin @Inject constructor(val depFactory: DepFactory, val executors: KobaltExecutors) + : BasePlugin(), ICompilerFlagContributor { companion object { - public const val TASK_APT: String = "runApt" + const val TASK_APT: String = "runApt" + const val NAME = "apt" } - override val name = "apt" + override val name = NAME - @Task(name = TASK_APT, description = "Run apt", runBefore = arrayOf("compile")) - fun taskApt(project: Project) : TaskResult { - log(1, "apt called on ${project} with processors ${processors}") - return TaskResult() + private val configs = hashMapOf() + + fun addAptConfig(project: Project, config: AptConfig) { + configs.put(project.name, config) } - private val processors = arrayListOf() + // ICompilerFlagContributor + override fun flagsFor(project: Project) : List { + val result = arrayListOf() + configs[project.name]?.let { config -> + aptDependencies.get(key = project.name)?.let { aptDependency -> + val dependency = depFactory.create(aptDependency, executors.miscExecutor) + result.add("-processorpath") + result.add(dependency.jarFile.get().absolutePath) + val generated = KFiles.joinAndMakeDir(project.directory, project.buildDirectory!!, config.outputDir) + result.add("-s") + result.add(generated) + } + } + log(2, "New flags from apt: " + result.joinToString(" ")) + return result + } - fun addApt(dep: String) { - processors.add(dep) + private val aptDependencies = hashMapOf() + fun addAptDependency(dependencies: Dependencies, it: String) { + aptDependencies.put(dependencies.project.name, it) + } +} + +class AptConfig(var outputDir: String = "generated/sources/apt") + +@Directive +public fun Project.apt(init: AptConfig.() -> Unit) { + AptConfig().let { + it.init() + (Kobalt.findPlugin(AptPlugin.NAME) as AptPlugin).addAptConfig(this, it) } } @Directive -public fun Dependencies.apt(dep: String) { - (Kobalt.findPlugin("apt") as AptPlugin).addApt(dep) -} \ No newline at end of file +fun Dependencies.apt(vararg dep: String) { + dep.forEach { + (Kobalt.findPlugin(AptPlugin.NAME) as AptPlugin).addAptDependency(this, it) + } +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 464dd988..9e9fec37 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -9,6 +9,7 @@ com.beust.kobalt.plugin.kotlin.KotlinPlugin com.beust.kobalt.plugin.packaging.PackagingPlugin com.beust.kobalt.plugin.publish.PublishPlugin + com.beust.kobalt.plugin.apt.AptPlugin com.beust.kobalt.plugin.android.AndroidPlugin @@ -25,4 +26,7 @@ com.beust.kobalt.plugin.android.AndroidPlugin + + com.beust.kobalt.plugin.apt.AptPlugin + \ No newline at end of file