[CLI] Arguments: Implement raw vs resolved delimiters
KTIJ-24976
This commit is contained in:
committed by
Space Team
parent
d07b1b6502
commit
7f91e94e7a
@@ -10,6 +10,7 @@ package org.jetbrains.kotlin.compilerRunner
|
|||||||
import org.jetbrains.kotlin.cli.common.arguments.Argument
|
import org.jetbrains.kotlin.cli.common.arguments.Argument
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
|
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.isAdvanced
|
import org.jetbrains.kotlin.cli.common.arguments.isAdvanced
|
||||||
|
import org.jetbrains.kotlin.cli.common.arguments.resolvedDelimiter
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.full.findAnnotation
|
import kotlin.reflect.full.findAnnotation
|
||||||
import kotlin.reflect.full.memberProperties
|
import kotlin.reflect.full.memberProperties
|
||||||
@@ -31,8 +32,8 @@ internal fun <T : CommonToolArguments> toArgumentStrings(thisArguments: T, type:
|
|||||||
val rawPropertyValue = property.get(thisArguments)
|
val rawPropertyValue = property.get(thisArguments)
|
||||||
val rawDefaultValue = property.get(defaultArguments)
|
val rawDefaultValue = property.get(defaultArguments)
|
||||||
|
|
||||||
/* Default value can be omitted when not marked as 'isExplicit' */
|
/* Default value can be omitted */
|
||||||
if (rawPropertyValue == rawDefaultValue && !argumentAnnotation.isExplicit) {
|
if (rawPropertyValue == rawDefaultValue) {
|
||||||
return@forEach
|
return@forEach
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,8 +79,8 @@ internal fun <T : CommonToolArguments> toArgumentStrings(thisArguments: T, type:
|
|||||||
|
|
||||||
private fun getArgumentStringValue(argumentAnnotation: Argument, values: Array<*>?): List<String> {
|
private fun getArgumentStringValue(argumentAnnotation: Argument, values: Array<*>?): List<String> {
|
||||||
if (values.isNullOrEmpty()) return emptyList()
|
if (values.isNullOrEmpty()) return emptyList()
|
||||||
val delimiter = argumentAnnotation.delimiter
|
val delimiter = argumentAnnotation.resolvedDelimiter
|
||||||
return if (delimiter.isEmpty()) values.map { it.toString() }
|
return if (delimiter.isNullOrEmpty()) values.map { it.toString() }
|
||||||
else listOf(values.joinToString(delimiter))
|
else listOf(values.joinToString(delimiter))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -188,7 +188,7 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
|||||||
value = "-Xcompiler-plugin",
|
value = "-Xcompiler-plugin",
|
||||||
valueDescription = "<path1>,<path2>:<optionName>=<value>,<optionName>=<value>",
|
valueDescription = "<path1>,<path2>:<optionName>=<value>,<optionName>=<value>",
|
||||||
description = "Register compiler plugin",
|
description = "Register compiler plugin",
|
||||||
delimiter = ""
|
delimiter = Argument.Delimiters.none
|
||||||
)
|
)
|
||||||
var pluginConfigurations: Array<String>? = null
|
var pluginConfigurations: Array<String>? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
|
|||||||
+11
-11
@@ -44,7 +44,7 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
@Argument(value="-include-binary", deprecatedName = "-includeBinary", shortName = "-ib", valueDescription = "<path>", description = "Pack external binary within the klib")
|
@Argument(value="-include-binary", deprecatedName = "-includeBinary", shortName = "-ib", valueDescription = "<path>", description = "Pack external binary within the klib")
|
||||||
var includeBinaries: Array<String>? = null
|
var includeBinaries: Array<String>? = null
|
||||||
|
|
||||||
@Argument(value = "-library", shortName = "-l", valueDescription = "<path>", description = "Link with the library", delimiter = "")
|
@Argument(value = "-library", shortName = "-l", valueDescription = "<path>", description = "Link with the library", delimiter = Argument.Delimiters.none)
|
||||||
var libraries: Array<String>? = null
|
var libraries: Array<String>? = null
|
||||||
|
|
||||||
@Argument(value = "-library-version", shortName = "-lv", valueDescription = "<version>", description = "Set library version")
|
@Argument(value = "-library-version", shortName = "-lv", valueDescription = "<version>", description = "Set library version")
|
||||||
@@ -76,7 +76,7 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
deprecatedName = "-nativelibrary",
|
deprecatedName = "-nativelibrary",
|
||||||
shortName = "-nl",
|
shortName = "-nl",
|
||||||
valueDescription = "<path>",
|
valueDescription = "<path>",
|
||||||
description = "Include the native bitcode library", delimiter = ""
|
description = "Include the native bitcode library", delimiter = Argument.Delimiters.none
|
||||||
)
|
)
|
||||||
var nativeLibraries: Array<String>? = null
|
var nativeLibraries: Array<String>? = null
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
@Argument(value="-linker-options", deprecatedName = "-linkerOpts", valueDescription = "<arg>", description = "Pass arguments to linker", delimiter = " ")
|
@Argument(value="-linker-options", deprecatedName = "-linkerOpts", valueDescription = "<arg>", description = "Pass arguments to linker", delimiter = " ")
|
||||||
var linkerArguments: Array<String>? = null
|
var linkerArguments: Array<String>? = null
|
||||||
|
|
||||||
@Argument(value="-linker-option", valueDescription = "<arg>", description = "Pass argument to linker", delimiter = "")
|
@Argument(value="-linker-option", valueDescription = "<arg>", description = "Pass argument to linker", delimiter = Argument.Delimiters.none)
|
||||||
var singleLinkerArguments: Array<String>? = null
|
var singleLinkerArguments: Array<String>? = null
|
||||||
|
|
||||||
@Argument(value = "-nostdlib", description = "Don't link with stdlib")
|
@Argument(value = "-nostdlib", description = "Don't link with stdlib")
|
||||||
@@ -138,7 +138,7 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
value = "-Xcache-directory",
|
value = "-Xcache-directory",
|
||||||
valueDescription = "<path>",
|
valueDescription = "<path>",
|
||||||
description = "Path to the directory containing caches",
|
description = "Path to the directory containing caches",
|
||||||
delimiter = ""
|
delimiter = Argument.Delimiters.none
|
||||||
)
|
)
|
||||||
var cacheDirectories: Array<String>? = null
|
var cacheDirectories: Array<String>? = null
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
value = CACHED_LIBRARY,
|
value = CACHED_LIBRARY,
|
||||||
valueDescription = "<library path>,<cache path>",
|
valueDescription = "<library path>,<cache path>",
|
||||||
description = "Comma-separated paths of a library and its cache",
|
description = "Comma-separated paths of a library and its cache",
|
||||||
delimiter = ""
|
delimiter = Argument.Delimiters.none
|
||||||
)
|
)
|
||||||
var cachedLibraries: Array<String>? = null
|
var cachedLibraries: Array<String>? = null
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
valueDescription = "<path>",
|
valueDescription = "<path>",
|
||||||
description = "Path to the root directory from which dependencies are to be cached automatically.\n" +
|
description = "Path to the root directory from which dependencies are to be cached automatically.\n" +
|
||||||
"By default caches will be placed into the kotlin-native system cache directory.",
|
"By default caches will be placed into the kotlin-native system cache directory.",
|
||||||
delimiter = ""
|
delimiter = Argument.Delimiters.none
|
||||||
)
|
)
|
||||||
var autoCacheableFrom: Array<String>? = null
|
var autoCacheableFrom: Array<String>? = null
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
value = "-Xauto-cache-dir",
|
value = "-Xauto-cache-dir",
|
||||||
valueDescription = "<path>",
|
valueDescription = "<path>",
|
||||||
description = "Path to the directory where to put caches for auto-cacheable dependencies",
|
description = "Path to the directory where to put caches for auto-cacheable dependencies",
|
||||||
delimiter = ""
|
delimiter = Argument.Delimiters.none
|
||||||
)
|
)
|
||||||
var autoCacheDir: String? = null
|
var autoCacheDir: String? = null
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
valueDescription = "<path>",
|
valueDescription = "<path>",
|
||||||
description = "A library to be included into produced framework API.\n" +
|
description = "A library to be included into produced framework API.\n" +
|
||||||
"Must be one of libraries passed with '-library'",
|
"Must be one of libraries passed with '-library'",
|
||||||
delimiter = ""
|
delimiter = Argument.Delimiters.none
|
||||||
)
|
)
|
||||||
var exportedLibraries: Array<String>? = null
|
var exportedLibraries: Array<String>? = null
|
||||||
|
|
||||||
@@ -232,7 +232,7 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
value = ADD_CACHE,
|
value = ADD_CACHE,
|
||||||
valueDescription = "<path>",
|
valueDescription = "<path>",
|
||||||
description = "Path to the library to be added to cache",
|
description = "Path to the library to be added to cache",
|
||||||
delimiter = ""
|
delimiter = Argument.Delimiters.none
|
||||||
)
|
)
|
||||||
var libraryToAddToCache: String? = null
|
var libraryToAddToCache: String? = null
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
value = "-Xfile-to-cache",
|
value = "-Xfile-to-cache",
|
||||||
valueDescription = "<path>",
|
valueDescription = "<path>",
|
||||||
description = "Path to file to cache",
|
description = "Path to file to cache",
|
||||||
delimiter = ""
|
delimiter = Argument.Delimiters.none
|
||||||
)
|
)
|
||||||
var filesToCache: Array<String>? = null
|
var filesToCache: Array<String>? = null
|
||||||
|
|
||||||
@@ -341,7 +341,7 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
valueDescription = "<path>",
|
valueDescription = "<path>",
|
||||||
description = "Provide code coverage for the given library.\n" +
|
description = "Provide code coverage for the given library.\n" +
|
||||||
"Must be one of libraries passed with '-library'",
|
"Must be one of libraries passed with '-library'",
|
||||||
delimiter = ""
|
delimiter = Argument.Delimiters.none
|
||||||
)
|
)
|
||||||
var coveredLibraries: Array<String>? = null
|
var coveredLibraries: Array<String>? = null
|
||||||
|
|
||||||
|
|||||||
+27
-5
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.cli.common.arguments
|
package org.jetbrains.kotlin.cli.common.arguments
|
||||||
|
|
||||||
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties
|
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties
|
||||||
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.KMutableProperty1
|
import kotlin.reflect.KMutableProperty1
|
||||||
@@ -28,14 +29,35 @@ annotation class Argument(
|
|||||||
val value: String,
|
val value: String,
|
||||||
val shortName: String = "",
|
val shortName: String = "",
|
||||||
val deprecatedName: String = "",
|
val deprecatedName: String = "",
|
||||||
val delimiter: String = ",",
|
@property:RawDelimiter
|
||||||
|
val delimiter: String = Delimiters.default,
|
||||||
val valueDescription: String = "",
|
val valueDescription: String = "",
|
||||||
val description: String
|
val description: String
|
||||||
)
|
) {
|
||||||
|
@RequiresOptIn(
|
||||||
|
message = "The raw delimiter value needs to be resolved. See 'resolvedDelimiter'. Using the raw value requires opt-in",
|
||||||
|
level = RequiresOptIn.Level.ERROR
|
||||||
|
)
|
||||||
|
annotation class RawDelimiter
|
||||||
|
|
||||||
|
object Delimiters {
|
||||||
|
const val default = ","
|
||||||
|
const val none = ""
|
||||||
|
const val pathSeparator = "<path_separator>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val Argument.isAdvanced: Boolean
|
val Argument.isAdvanced: Boolean
|
||||||
get() = value.startsWith(ADVANCED_ARGUMENT_PREFIX) && value.length > ADVANCED_ARGUMENT_PREFIX.length
|
get() = value.startsWith(ADVANCED_ARGUMENT_PREFIX) && value.length > ADVANCED_ARGUMENT_PREFIX.length
|
||||||
|
|
||||||
|
@OptIn(Argument.RawDelimiter::class)
|
||||||
|
val Argument.resolvedDelimiter: String?
|
||||||
|
get() = when (delimiter) {
|
||||||
|
Argument.Delimiters.none -> null
|
||||||
|
Argument.Delimiters.pathSeparator -> File.pathSeparator
|
||||||
|
else -> delimiter
|
||||||
|
}
|
||||||
|
|
||||||
private const val ADVANCED_ARGUMENT_PREFIX = "-X"
|
private const val ADVANCED_ARGUMENT_PREFIX = "-X"
|
||||||
private const val FREE_ARGS_DELIMITER = "--"
|
private const val FREE_ARGS_DELIMITER = "--"
|
||||||
|
|
||||||
@@ -211,7 +233,7 @@ private fun <A : CommonToolArguments> parsePreprocessedCommandLineArguments(
|
|||||||
errors.value.duplicateArguments[argument.value] = value
|
errors.value.duplicateArguments[argument.value] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
updateField(property, result, value, argument.delimiter, overrideArguments)
|
updateField(property, result, value, argument.resolvedDelimiter, overrideArguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
result.freeArgs += freeArgs
|
result.freeArgs += freeArgs
|
||||||
@@ -238,13 +260,13 @@ private fun <A : CommonToolArguments> updateField(
|
|||||||
property: KMutableProperty1<A, Any?>,
|
property: KMutableProperty1<A, Any?>,
|
||||||
result: A,
|
result: A,
|
||||||
value: Any,
|
value: Any,
|
||||||
delimiter: String,
|
delimiter: String?,
|
||||||
overrideArguments: Boolean
|
overrideArguments: Boolean
|
||||||
) {
|
) {
|
||||||
when (property.returnType.classifier) {
|
when (property.returnType.classifier) {
|
||||||
Boolean::class, String::class -> property.set(result, value)
|
Boolean::class, String::class -> property.set(result, value)
|
||||||
Array<String>::class -> {
|
Array<String>::class -> {
|
||||||
val newElements = if (delimiter.isEmpty()) {
|
val newElements = if (delimiter.isNullOrEmpty()) {
|
||||||
arrayOf(value as String)
|
arrayOf(value as String)
|
||||||
} else {
|
} else {
|
||||||
(value as String).split(delimiter).toTypedArray()
|
(value as String).split(delimiter).toTypedArray()
|
||||||
|
|||||||
Reference in New Issue
Block a user