Kapt3: Serialize annotation processor options to base64 to support spaces in option values
This commit is contained in:
+2
-1
@@ -108,7 +108,8 @@ class Kapt3IT : BaseGradleIT() {
|
|||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
assertKaptSuccessful()
|
assertKaptSuccessful()
|
||||||
assertContains("Options: {suffix=Customized, justColon=:, justEquals==, containsColon=a:b, " +
|
assertContains("Options: {suffix=Customized, justColon=:, justEquals==, containsColon=a:b, " +
|
||||||
"containsEquals=a=b, startsWithColon=:a, startsWithEquals==a, endsWithColon=a:, endsWithEquals=a:}")
|
"containsEquals=a=b, startsWithColon=:a, startsWithEquals==a, endsWithColon=a:, " +
|
||||||
|
"endsWithEquals=a:, withSpace=a b c}")
|
||||||
assertFileExists("build/generated/source/kapt/main/example/TestClassCustomized.java")
|
assertFileExists("build/generated/source/kapt/main/example/TestClassCustomized.java")
|
||||||
assertFileExists("build/classes/main/example/TestClass.class")
|
assertFileExists("build/classes/main/example/TestClass.class")
|
||||||
assertFileExists("build/classes/main/example/TestClassCustomized.class")
|
assertFileExists("build/classes/main/example/TestClassCustomized.class")
|
||||||
|
|||||||
+1
@@ -31,5 +31,6 @@ kapt {
|
|||||||
arg("startsWithEquals", "=a")
|
arg("startsWithEquals", "=a")
|
||||||
arg("endsWithColon", "a:")
|
arg("endsWithColon", "a:")
|
||||||
arg("endsWithEquals", "a:")
|
arg("endsWithEquals", "a:")
|
||||||
|
arg("withSpace", "a b c") // key doesn't support spaces
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+19
-4
@@ -29,8 +29,11 @@ import org.gradle.api.tasks.compile.JavaCompile
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
|
import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
import org.jetbrains.kotlin.gradle.tasks.SyncOutputTask
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.io.ObjectOutputStream
|
||||||
|
import javax.xml.bind.DatatypeConverter
|
||||||
|
import javax.xml.bind.DatatypeConverter.printBase64Binary
|
||||||
|
|
||||||
// apply plugin: 'kotlin-kapt'
|
// apply plugin: 'kotlin-kapt'
|
||||||
class Kapt3GradleSubplugin : Plugin<Project> {
|
class Kapt3GradleSubplugin : Plugin<Project> {
|
||||||
@@ -171,15 +174,27 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
|||||||
|
|
||||||
val apOptions = kaptExtension.getAdditionalArguments(project, variantData, androidPlugin) + androidOptions
|
val apOptions = kaptExtension.getAdditionalArguments(project, variantData, androidPlugin) + androidOptions
|
||||||
|
|
||||||
for ((key, value) in apOptions) {
|
SubpluginOption("apoptions", encodeAnnotationProcessingOptions(apOptions))
|
||||||
pluginOptions += SubpluginOption("apoption", "$key:$value")
|
|
||||||
}
|
|
||||||
|
|
||||||
addMiscOptions(pluginOptions)
|
addMiscOptions(pluginOptions)
|
||||||
|
|
||||||
return pluginOptions
|
return pluginOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun encodeAnnotationProcessingOptions(options: Map<String, String>): String {
|
||||||
|
val os = ByteArrayOutputStream()
|
||||||
|
val oos = ObjectOutputStream(os)
|
||||||
|
|
||||||
|
oos.writeInt(options.size)
|
||||||
|
for ((k, v) in options.entries) {
|
||||||
|
oos.writeUTF(k)
|
||||||
|
oos.writeUTF(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
oos.flush()
|
||||||
|
return printBase64Binary(os.toByteArray())
|
||||||
|
}
|
||||||
|
|
||||||
private fun Kapt3SubpluginContext.addMiscOptions(pluginOptions: MutableList<SubpluginOption>) {
|
private fun Kapt3SubpluginContext.addMiscOptions(pluginOptions: MutableList<SubpluginOption>) {
|
||||||
if (kaptExtension.generateStubs) {
|
if (kaptExtension.generateStubs) {
|
||||||
project.logger.warn("'kapt.generateStubs' is not used by the 'kotlin-kapt' plugin")
|
project.logger.warn("'kapt.generateStubs' is not used by the 'kotlin-kapt' plugin")
|
||||||
|
|||||||
@@ -37,15 +37,16 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
|||||||
import org.jetbrains.kotlin.container.ComponentProvider
|
import org.jetbrains.kotlin.container.ComponentProvider
|
||||||
import org.jetbrains.kotlin.context.ProjectContext
|
import org.jetbrains.kotlin.context.ProjectContext
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||||
import org.jetbrains.kotlin.kapt3.diagnostic.DefaultErrorMessagesKapt3
|
import org.jetbrains.kotlin.kapt3.diagnostic.DefaultErrorMessagesKapt3
|
||||||
import org.jetbrains.kotlin.kapt3.util.KaptLogger
|
import org.jetbrains.kotlin.kapt3.util.KaptLogger
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
|
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.io.ObjectInputStream
|
||||||
|
import javax.xml.bind.DatatypeConverter
|
||||||
|
|
||||||
object Kapt3ConfigurationKeys {
|
object Kapt3ConfigurationKeys {
|
||||||
val SOURCE_OUTPUT_DIR: CompilerConfigurationKey<String> =
|
val SOURCE_OUTPUT_DIR: CompilerConfigurationKey<String> =
|
||||||
@@ -63,8 +64,8 @@ object Kapt3ConfigurationKeys {
|
|||||||
val ANNOTATION_PROCESSOR_CLASSPATH: CompilerConfigurationKey<List<String>> =
|
val ANNOTATION_PROCESSOR_CLASSPATH: CompilerConfigurationKey<List<String>> =
|
||||||
CompilerConfigurationKey.create<List<String>>("annotation processor classpath")
|
CompilerConfigurationKey.create<List<String>>("annotation processor classpath")
|
||||||
|
|
||||||
val APT_OPTIONS: CompilerConfigurationKey<List<String>> =
|
val APT_OPTIONS: CompilerConfigurationKey<String> =
|
||||||
CompilerConfigurationKey.create<List<String>>("annotation processing options")
|
CompilerConfigurationKey.create<String>("annotation processing options")
|
||||||
|
|
||||||
val VERBOSE_MODE: CompilerConfigurationKey<String> =
|
val VERBOSE_MODE: CompilerConfigurationKey<String> =
|
||||||
CompilerConfigurationKey.create<String>("verbose mode")
|
CompilerConfigurationKey.create<String>("verbose mode")
|
||||||
@@ -100,8 +101,8 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
|
|||||||
required = false, allowMultipleOccurrences = true)
|
required = false, allowMultipleOccurrences = true)
|
||||||
|
|
||||||
val APT_OPTIONS_OPTION: CliOption =
|
val APT_OPTIONS_OPTION: CliOption =
|
||||||
CliOption("apoption", "<key>:<value>", "Annotation processor option",
|
CliOption("apoptions", "options map", "Encoded annotation processor options",
|
||||||
required = false, allowMultipleOccurrences = true)
|
required = false, allowMultipleOccurrences = false)
|
||||||
|
|
||||||
val VERBOSE_MODE_OPTION: CliOption =
|
val VERBOSE_MODE_OPTION: CliOption =
|
||||||
CliOption("verbose", "true | false", "Enable verbose output", required = false)
|
CliOption("verbose", "true | false", "Enable verbose output", required = false)
|
||||||
@@ -126,7 +127,7 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
|
|||||||
override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) {
|
override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) {
|
||||||
when (option) {
|
when (option) {
|
||||||
ANNOTATION_PROCESSOR_CLASSPATH_OPTION -> configuration.appendList(ANNOTATION_PROCESSOR_CLASSPATH, value)
|
ANNOTATION_PROCESSOR_CLASSPATH_OPTION -> configuration.appendList(ANNOTATION_PROCESSOR_CLASSPATH, value)
|
||||||
APT_OPTIONS_OPTION -> configuration.appendList(APT_OPTIONS, value)
|
APT_OPTIONS_OPTION -> configuration.put(Kapt3ConfigurationKeys.APT_OPTIONS, value)
|
||||||
SOURCE_OUTPUT_DIR_OPTION -> configuration.put(Kapt3ConfigurationKeys.SOURCE_OUTPUT_DIR, value)
|
SOURCE_OUTPUT_DIR_OPTION -> configuration.put(Kapt3ConfigurationKeys.SOURCE_OUTPUT_DIR, value)
|
||||||
CLASS_OUTPUT_DIR_OPTION -> configuration.put(Kapt3ConfigurationKeys.CLASS_OUTPUT_DIR, value)
|
CLASS_OUTPUT_DIR_OPTION -> configuration.put(Kapt3ConfigurationKeys.CLASS_OUTPUT_DIR, value)
|
||||||
STUBS_OUTPUT_DIR_OPTION -> configuration.put(Kapt3ConfigurationKeys.STUBS_OUTPUT_DIR, value)
|
STUBS_OUTPUT_DIR_OPTION -> configuration.put(Kapt3ConfigurationKeys.STUBS_OUTPUT_DIR, value)
|
||||||
@@ -141,6 +142,24 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Kapt3ComponentRegistrar : ComponentRegistrar {
|
class Kapt3ComponentRegistrar : ComponentRegistrar {
|
||||||
|
fun decodeAnnotationProcessingOptions(options: String): Map<String, String> {
|
||||||
|
val map = LinkedHashMap<String, String>()
|
||||||
|
|
||||||
|
val decodedBytes = DatatypeConverter.parseBase64Binary(options)
|
||||||
|
val bis = ByteArrayInputStream(decodedBytes)
|
||||||
|
val ois = ObjectInputStream(bis)
|
||||||
|
|
||||||
|
val n = ois.readInt()
|
||||||
|
|
||||||
|
repeat(n) {
|
||||||
|
val k = ois.readUTF()
|
||||||
|
val v = ois.readUTF()
|
||||||
|
map[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
|
||||||
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
|
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
|
||||||
val isAptOnly = configuration.get(Kapt3ConfigurationKeys.APT_ONLY) == "true"
|
val isAptOnly = configuration.get(Kapt3ConfigurationKeys.APT_ONLY) == "true"
|
||||||
val isVerbose = configuration.get(Kapt3ConfigurationKeys.VERBOSE_MODE) == "true"
|
val isVerbose = configuration.get(Kapt3ConfigurationKeys.VERBOSE_MODE) == "true"
|
||||||
@@ -170,11 +189,7 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val apOptions = (configuration.get(APT_OPTIONS) ?: listOf())
|
val apOptions = configuration.get(APT_OPTIONS)?.let { decodeAnnotationProcessingOptions(it) } ?: emptyMap()
|
||||||
.map { it.split(':', limit = 2) }
|
|
||||||
.filter { it.isNotEmpty() }
|
|
||||||
.map { it[0] to it.getOrElse(1) { "" } }
|
|
||||||
.toMap()
|
|
||||||
|
|
||||||
sourcesOutputDir.mkdirs()
|
sourcesOutputDir.mkdirs()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user