Introduce AbstractCliOption, rewrite all possible kapt options as enum values
This commit is contained in:
@@ -84,12 +84,14 @@ object PluginCliParser {
|
||||
it.pluginId
|
||||
} ?: mapOf()
|
||||
|
||||
// TODO issue a warning on using deprecated command line processors when all official plugin migrate to the newer convention
|
||||
|
||||
val commandLineProcessors = ServiceLoader.load(CommandLineProcessor::class.java, classLoader).toMutableList()
|
||||
commandLineProcessors.addAll(BundledCompilerPlugins.commandLineProcessors)
|
||||
|
||||
for (processor in commandLineProcessors) {
|
||||
val declaredOptions = processor.pluginOptions.associateBy { it.name }
|
||||
val optionsToValues = MultiMap<CliOption, CliOptionValue>()
|
||||
val declaredOptions = processor.pluginOptions.associateBy { it.optionName }
|
||||
val optionsToValues = MultiMap<AbstractCliOption, CliOptionValue>()
|
||||
|
||||
for (optionValue in optionValuesByPlugin[processor.pluginId].orEmpty()) {
|
||||
val option = declaredOptions[optionValue!!.optionName]
|
||||
@@ -103,14 +105,14 @@ object PluginCliParser {
|
||||
throw PluginCliOptionProcessingException(
|
||||
processor.pluginId,
|
||||
processor.pluginOptions,
|
||||
"Required plugin option not present: ${processor.pluginId}:${option.name}"
|
||||
"Required plugin option not present: ${processor.pluginId}:${option.optionName}"
|
||||
)
|
||||
}
|
||||
if (!option.allowMultipleOccurrences && values.size > 1) {
|
||||
throw PluginCliOptionProcessingException(
|
||||
processor.pluginId,
|
||||
processor.pluginOptions,
|
||||
"Multiple values are not allowed for plugin option ${processor.pluginId}:${option.name}"
|
||||
"Multiple values are not allowed for plugin option ${processor.pluginId}:${option.optionName}"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,29 +18,41 @@ package org.jetbrains.kotlin.compiler.plugin
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
interface AbstractCliOption {
|
||||
val optionName: String
|
||||
val valueDescription: String
|
||||
val description: String
|
||||
val required: Boolean
|
||||
val allowMultipleOccurrences: Boolean
|
||||
}
|
||||
|
||||
class CliOption(
|
||||
val name: String,
|
||||
val valueDescription: String,
|
||||
val description: String,
|
||||
val required: Boolean = true,
|
||||
val allowMultipleOccurrences: Boolean = false
|
||||
)
|
||||
override val optionName: String,
|
||||
override val valueDescription: String,
|
||||
override val description: String,
|
||||
override val required: Boolean = true,
|
||||
override val allowMultipleOccurrences: Boolean = false
|
||||
) : AbstractCliOption {
|
||||
@Deprecated("Use optionName instead.", ReplaceWith("optionName"))
|
||||
val name: String
|
||||
get() = optionName
|
||||
}
|
||||
|
||||
open class CliOptionProcessingException(message: String, cause: Throwable? = null): RuntimeException(message, cause)
|
||||
|
||||
class PluginCliOptionProcessingException(
|
||||
val pluginId: String,
|
||||
val options: Collection<CliOption>,
|
||||
val options: Collection<AbstractCliOption>,
|
||||
message: String,
|
||||
cause: Throwable? = null
|
||||
): CliOptionProcessingException(message, cause)
|
||||
|
||||
fun cliPluginUsageString(pluginId: String, options: Collection<CliOption>): String {
|
||||
fun cliPluginUsageString(pluginId: String, options: Collection<AbstractCliOption>): String {
|
||||
val LEFT_INDENT = 2
|
||||
val MAX_OPTION_WIDTH = 26
|
||||
|
||||
val renderedOptions = options.map {
|
||||
val name = "${it.name} ${it.valueDescription}"
|
||||
val name = "${it.optionName} ${it.valueDescription}"
|
||||
val margin = if (name.length > MAX_OPTION_WIDTH) {
|
||||
"\n" + " ".repeat(MAX_OPTION_WIDTH + LEFT_INDENT + 1)
|
||||
} else " ".repeat(1 + MAX_OPTION_WIDTH - name.length)
|
||||
|
||||
+13
-4
@@ -21,9 +21,18 @@ import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||
|
||||
interface CommandLineProcessor {
|
||||
val pluginId: String
|
||||
val pluginOptions: Collection<CliOption>
|
||||
val pluginOptions: Collection<AbstractCliOption>
|
||||
|
||||
@Throws(CliOptionProcessingException::class) fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration)
|
||||
@Throws(CliOptionProcessingException::class)
|
||||
fun processOption(option: AbstractCliOption, value: String, configuration: CompilerConfiguration) {
|
||||
@Suppress("DEPRECATION")
|
||||
processOption(option as CliOption, value, configuration)
|
||||
}
|
||||
|
||||
// TODO remove processOption(AbstractCliOption, ...) implementation after removal of this.
|
||||
@Deprecated("Implement processOption(option: AbstractCliOption, value: String, configuration: CompilerConfiguration) instead.")
|
||||
@Throws(CliOptionProcessingException::class)
|
||||
fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) {}
|
||||
|
||||
fun <T> CompilerConfiguration.appendList(option: CompilerConfigurationKey<List<T>>, value: T) {
|
||||
val paths = getList(option).toMutableList()
|
||||
@@ -37,9 +46,9 @@ interface CommandLineProcessor {
|
||||
put(option, paths)
|
||||
}
|
||||
|
||||
fun CompilerConfiguration.applyOptionsFrom(map: Map<String, List<String>>, pluginOptions: Collection<CliOption>) {
|
||||
fun CompilerConfiguration.applyOptionsFrom(map: Map<String, List<String>>, pluginOptions: Collection<AbstractCliOption>) {
|
||||
for ((key, values) in map) {
|
||||
val option = pluginOptions.firstOrNull { it.name == key } ?: continue
|
||||
val option = pluginOptions.firstOrNull { it.optionName == key } ?: continue
|
||||
|
||||
for (value in values) {
|
||||
processOption(option, value, this)
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ class MavenPluginComponent : KotlinMavenPluginExtension {
|
||||
return listOf(PluginOption(
|
||||
"test-me",
|
||||
TestCommandLineProcessor.TestPluginId,
|
||||
TestCommandLineProcessor.MyTestOption.name,
|
||||
TestCommandLineProcessor.MyTestOption.optionName,
|
||||
"my-special-value"))
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -25,7 +25,7 @@ class TestCommandLineProcessor : CommandLineProcessor {
|
||||
MyTestOption -> {
|
||||
configuration.put(TestPluginKeys.TestOption, value)
|
||||
}
|
||||
else -> throw CliOptionProcessingException("Unknown option: ${option.name}")
|
||||
else -> throw CliOptionProcessingException("Unknown option: ${option.optionName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||
|
||||
object ImportsDumperCliOptions {
|
||||
val DESTINATION = CliOption(
|
||||
name = "output-imports",
|
||||
optionName = "output-imports",
|
||||
valueDescription = "<path>",
|
||||
description = "Output imports from all compiled files to the specified file in JSON format",
|
||||
required = false // non-required because importsDumper is a bundled plugin
|
||||
|
||||
@@ -24,10 +24,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
|
||||
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||
import org.jetbrains.kotlin.compiler.plugin.CliOption
|
||||
import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException
|
||||
import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
|
||||
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
||||
import org.jetbrains.kotlin.compiler.plugin.*
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||
@@ -38,25 +35,11 @@ import org.jetbrains.kotlin.container.useInstance
|
||||
import org.jetbrains.kotlin.context.ProjectContext
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.ANNOTATION_PROCESSORS_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.ANNOTATION_PROCESSOR_CLASSPATH_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.APT_MODE_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.APT_ONLY_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.APT_OPTIONS_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.CLASS_OUTPUT_DIR_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.CORRECT_ERROR_TYPES_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.INCREMENTAL_DATA_OUTPUT_DIR_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.INFO_AS_WARNINGS_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.JAVAC_CLI_OPTIONS_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.MAP_DIAGNOSTIC_LOCATIONS_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.SOURCE_OUTPUT_DIR_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.STUBS_OUTPUT_DIR_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.USE_LIGHT_ANALYSIS_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.VERBOSE_MODE_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.KaptCliOptions.*
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3ConfigurationKeys.ANNOTATION_PROCESSOR_CLASSPATH
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3ConfigurationKeys.APT_OPTIONS
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3ConfigurationKeys.JAVAC_CLI_OPTIONS
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.STRICT_MODE_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.KaptCliOptions.Companion.ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID
|
||||
import org.jetbrains.kotlin.kapt3.base.Kapt
|
||||
import org.jetbrains.kotlin.kapt3.base.KaptPaths
|
||||
import org.jetbrains.kotlin.kapt3.base.log
|
||||
@@ -123,100 +106,65 @@ object Kapt3ConfigurationKeys {
|
||||
CompilerConfigurationKey.create<String>(STRICT_MODE_OPTION.description)
|
||||
}
|
||||
|
||||
class Kapt3CommandLineProcessor : CommandLineProcessor {
|
||||
enum class KaptCliOptions(
|
||||
override val optionName: String,
|
||||
override val valueDescription: String,
|
||||
override val description: String,
|
||||
override val allowMultipleOccurrences: Boolean = false
|
||||
) : AbstractCliOption {
|
||||
CONFIGURATION("configuration", "<encoded>", "Encoded configuration"),
|
||||
SOURCE_OUTPUT_DIR_OPTION("sources", "<path>", "Output path for the generated files"),
|
||||
CLASS_OUTPUT_DIR_OPTION("classes", "<path>", "Output path for the class files"),
|
||||
STUBS_OUTPUT_DIR_OPTION("stubs", "<path>", "Output path for the Java stubs"),
|
||||
INCREMENTAL_DATA_OUTPUT_DIR_OPTION("incrementalData", "<path>", "Output path for the incremental data"),
|
||||
ANNOTATION_PROCESSOR_CLASSPATH_OPTION("apclasspath", "<classpath>", "Annotation processor classpath", true),
|
||||
APT_OPTIONS_OPTION("apoptions", "options map", "Encoded annotation processor options", false),
|
||||
JAVAC_CLI_OPTIONS_OPTION("javacArguments", "javac CLI options map", "Encoded javac CLI options", false),
|
||||
ANNOTATION_PROCESSORS_OPTION("processors", "<fqname,[fqname2,...]>", "Annotation processor qualified names", true),
|
||||
VERBOSE_MODE_OPTION("verbose", "true | false", "Enable verbose output"),
|
||||
INFO_AS_WARNINGS_OPTION("infoAsWarnings", "true | false", "Show information messages as warnings"),
|
||||
STRICT_MODE_OPTION("strict", "true | false", "Show errors on incompatibilities during stub generation"),
|
||||
APT_MODE_OPTION(
|
||||
"aptMode", "apt | stubs | stubsAndApt | compile",
|
||||
"Annotation processing mode: only apt, only stub generation, both, or with the subsequent compilation"
|
||||
),
|
||||
USE_LIGHT_ANALYSIS_OPTION(
|
||||
"useLightAnalysis",
|
||||
"true | false",
|
||||
"Do not analyze declaration bodies if can"
|
||||
),
|
||||
CORRECT_ERROR_TYPES_OPTION(
|
||||
"correctErrorTypes",
|
||||
"true | false",
|
||||
"Replace generated or error types with ones from the generated sources"
|
||||
),
|
||||
MAP_DIAGNOSTIC_LOCATIONS_OPTION(
|
||||
"mapDiagnosticLocations",
|
||||
"true | false",
|
||||
"Map diagnostic reported on kapt stubs to original locations in Kotlin sources"
|
||||
),
|
||||
|
||||
@Deprecated("Use APT_MODE_OPTION instead.")
|
||||
APT_ONLY_OPTION("aptOnly", "true | false", "Run only annotation processing, do not compile Kotlin files");
|
||||
|
||||
override val required: Boolean = false
|
||||
|
||||
companion object {
|
||||
const val ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID: String = "org.jetbrains.kotlin.kapt3"
|
||||
|
||||
val CONFIGURATION = CliOption("configuration", "<encoded>", "Encoded configuration", required = false)
|
||||
|
||||
val SOURCE_OUTPUT_DIR_OPTION: CliOption =
|
||||
CliOption("sources", "<path>", "Output path for the generated files", required = false)
|
||||
|
||||
val CLASS_OUTPUT_DIR_OPTION: CliOption =
|
||||
CliOption("classes", "<path>", "Output path for the class files", required = false)
|
||||
|
||||
val STUBS_OUTPUT_DIR_OPTION: CliOption =
|
||||
CliOption("stubs", "<path>", "Output path for the Java stubs", required = false)
|
||||
|
||||
val INCREMENTAL_DATA_OUTPUT_DIR_OPTION: CliOption =
|
||||
CliOption("incrementalData", "<path>", "Output path for the incremental data", required = false)
|
||||
|
||||
val ANNOTATION_PROCESSOR_CLASSPATH_OPTION: CliOption =
|
||||
CliOption(
|
||||
"apclasspath", "<classpath>", "Annotation processor classpath",
|
||||
required = false, allowMultipleOccurrences = true
|
||||
)
|
||||
|
||||
val APT_OPTIONS_OPTION: CliOption =
|
||||
CliOption(
|
||||
"apoptions", "options map", "Encoded annotation processor options",
|
||||
required = false, allowMultipleOccurrences = false
|
||||
)
|
||||
|
||||
val JAVAC_CLI_OPTIONS_OPTION: CliOption =
|
||||
CliOption(
|
||||
"javacArguments", "javac CLI options map", "Encoded javac CLI options",
|
||||
required = false, allowMultipleOccurrences = false
|
||||
)
|
||||
|
||||
val ANNOTATION_PROCESSORS_OPTION: CliOption =
|
||||
CliOption(
|
||||
"processors", "<fqname,[fqname2,...]>", "Annotation processor qualified names",
|
||||
required = false, allowMultipleOccurrences = true
|
||||
)
|
||||
|
||||
val VERBOSE_MODE_OPTION: CliOption =
|
||||
CliOption("verbose", "true | false", "Enable verbose output", required = false)
|
||||
|
||||
val INFO_AS_WARNINGS_OPTION: CliOption =
|
||||
CliOption("infoAsWarnings", "true | false", "Show information messages as warnings", required = false)
|
||||
|
||||
@Deprecated("Use APT_MODE_OPTION instead.")
|
||||
val APT_ONLY_OPTION: CliOption =
|
||||
CliOption("aptOnly", "true | false", "Run only annotation processing, do not compile Kotlin files", required = false)
|
||||
|
||||
val APT_MODE_OPTION: CliOption =
|
||||
CliOption(
|
||||
"aptMode", "apt | stubs | stubsAndApt | compile",
|
||||
"Annotation processing mode: only apt, only stub generation, both, or with the subsequent compilation",
|
||||
required = false
|
||||
)
|
||||
|
||||
val USE_LIGHT_ANALYSIS_OPTION: CliOption =
|
||||
CliOption("useLightAnalysis", "true | false", "Do not analyze declaration bodies if can", required = false)
|
||||
|
||||
val CORRECT_ERROR_TYPES_OPTION: CliOption =
|
||||
CliOption(
|
||||
"correctErrorTypes",
|
||||
"true | false",
|
||||
"Replace generated or error types with ones from the generated sources",
|
||||
required = false
|
||||
)
|
||||
|
||||
val MAP_DIAGNOSTIC_LOCATIONS_OPTION: CliOption =
|
||||
CliOption(
|
||||
"mapDiagnosticLocations",
|
||||
"true | false",
|
||||
"Map diagnostic reported on kapt stubs to original locations in Kotlin sources",
|
||||
required = false
|
||||
)
|
||||
|
||||
val STRICT_MODE_OPTION: CliOption =
|
||||
CliOption("strict", "true | false", "Show errors on incompatibilities during stub generation", required = false)
|
||||
}
|
||||
}
|
||||
|
||||
class Kapt3CommandLineProcessor : CommandLineProcessor {
|
||||
override val pluginId: String = ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID
|
||||
|
||||
override val pluginOptions: Collection<CliOption> =
|
||||
listOf(
|
||||
SOURCE_OUTPUT_DIR_OPTION, ANNOTATION_PROCESSOR_CLASSPATH_OPTION, APT_OPTIONS_OPTION, JAVAC_CLI_OPTIONS_OPTION,
|
||||
CLASS_OUTPUT_DIR_OPTION, VERBOSE_MODE_OPTION, STUBS_OUTPUT_DIR_OPTION, APT_ONLY_OPTION, APT_MODE_OPTION,
|
||||
USE_LIGHT_ANALYSIS_OPTION, CORRECT_ERROR_TYPES_OPTION, ANNOTATION_PROCESSORS_OPTION, INCREMENTAL_DATA_OUTPUT_DIR_OPTION,
|
||||
CONFIGURATION, MAP_DIAGNOSTIC_LOCATIONS_OPTION, INFO_AS_WARNINGS_OPTION, STRICT_MODE_OPTION
|
||||
)
|
||||
override val pluginOptions: Collection<AbstractCliOption> = KaptCliOptions.values().asList()
|
||||
|
||||
override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) {
|
||||
when (option) {
|
||||
override fun processOption(option: AbstractCliOption, value: String, configuration: CompilerConfiguration) {
|
||||
if (option !is KaptCliOptions) {
|
||||
throw CliOptionProcessingException("Unknown option: ${option.optionName}")
|
||||
}
|
||||
|
||||
return when (option) {
|
||||
ANNOTATION_PROCESSOR_CLASSPATH_OPTION -> configuration.appendList(ANNOTATION_PROCESSOR_CLASSPATH, value)
|
||||
ANNOTATION_PROCESSORS_OPTION -> configuration.appendList(
|
||||
Kapt3ConfigurationKeys.ANNOTATION_PROCESSORS, value.split(',').map { it.trim() }.filter { it.isNotEmpty() })
|
||||
@@ -235,7 +183,6 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
|
||||
INFO_AS_WARNINGS_OPTION -> configuration.put(Kapt3ConfigurationKeys.INFO_AS_WARNINGS, value)
|
||||
STRICT_MODE_OPTION -> configuration.put(Kapt3ConfigurationKeys.STRICT_MODE, value)
|
||||
CONFIGURATION -> configuration.applyOptionsFrom(decodePluginOptions(value), pluginOptions)
|
||||
else -> throw CliOptionProcessingException("Unknown option: ${option.name}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user