[CLI] argumentsToStrings: Add 'compactArgumentValues' option
Passing 'false' will pass Array or List based arguments multiple times instead of using the Delimiter. eg: compactArgumentValues = true: "-cp", "library1;library2;library3" compactArgumentValues = false: "-cp", "library1", "-cp", -"library2", "-cp", "library3" Using compactArgumentValues = false can be beneficial when the many compiler arguments are held in memory. In this case the raw arguments can intern individual string values, which is highly effective when the arguments refer to files on disk. KTIJ-24976
This commit is contained in:
committed by
Space Team
parent
fb66764c4d
commit
082a38216d
@@ -17,14 +17,20 @@ import kotlin.reflect.full.memberProperties
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@JvmOverloads
|
||||
fun CommonToolArguments.toArgumentStrings(useShortNames: Boolean = false): List<String> {
|
||||
fun CommonToolArguments.toArgumentStrings(shortArgumentKeys: Boolean = false, compactArgumentValues: Boolean = true): List<String> {
|
||||
return toArgumentStrings(
|
||||
this, this::class as KClass<CommonToolArguments>, useShortNames = useShortNames
|
||||
this, this::class as KClass<CommonToolArguments>,
|
||||
shortArgumentKeys = shortArgumentKeys,
|
||||
compactArgumentValues = compactArgumentValues
|
||||
)
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal fun <T : CommonToolArguments> toArgumentStrings(thisArguments: T, type: KClass<T>, useShortNames: Boolean): List<String> {
|
||||
internal fun <T : CommonToolArguments> toArgumentStrings(
|
||||
thisArguments: T, type: KClass<T>,
|
||||
shortArgumentKeys: Boolean,
|
||||
compactArgumentValues: Boolean
|
||||
): List<String> {
|
||||
val defaultArguments = type.newArgumentsInstance()
|
||||
val result = mutableListOf<String>()
|
||||
type.memberProperties.forEach { property ->
|
||||
@@ -41,15 +47,15 @@ internal fun <T : CommonToolArguments> toArgumentStrings(thisArguments: T, type:
|
||||
property.returnType.classifier == Boolean::class -> listOf(rawPropertyValue?.toString() ?: false.toString())
|
||||
|
||||
(property.returnType.classifier as? KClass<*>)?.java?.isArray == true ->
|
||||
getArgumentStringValue(argumentAnnotation, rawPropertyValue as Array<*>?)
|
||||
getArgumentStringValue(argumentAnnotation, rawPropertyValue as Array<*>?, compactArgumentValues)
|
||||
|
||||
property.returnType.classifier == List::class ->
|
||||
getArgumentStringValue(argumentAnnotation, (rawPropertyValue as List<*>?)?.toTypedArray())
|
||||
getArgumentStringValue(argumentAnnotation, (rawPropertyValue as List<*>?)?.toTypedArray(), compactArgumentValues)
|
||||
|
||||
else -> listOf(rawPropertyValue.toString())
|
||||
}
|
||||
|
||||
val argumentName = if (useShortNames && argumentAnnotation.shortName.isNotEmpty()) argumentAnnotation.shortName
|
||||
val argumentName = if (shortArgumentKeys && argumentAnnotation.shortName.isNotEmpty()) argumentAnnotation.shortName
|
||||
else argumentAnnotation.value
|
||||
|
||||
argumentStringValues.forEach { argumentStringValue ->
|
||||
@@ -77,10 +83,10 @@ internal fun <T : CommonToolArguments> toArgumentStrings(thisArguments: T, type:
|
||||
return result
|
||||
}
|
||||
|
||||
private fun getArgumentStringValue(argumentAnnotation: Argument, values: Array<*>?): List<String> {
|
||||
private fun getArgumentStringValue(argumentAnnotation: Argument, values: Array<*>?, compactArgumentValues: Boolean): List<String> {
|
||||
if (values.isNullOrEmpty()) return emptyList()
|
||||
val delimiter = argumentAnnotation.resolvedDelimiter
|
||||
return if (delimiter.isNullOrEmpty()) values.map { it.toString() }
|
||||
return if (delimiter.isNullOrEmpty() || !compactArgumentValues) values.map { it.toString() }
|
||||
else listOf(values.joinToString(delimiter))
|
||||
}
|
||||
|
||||
|
||||
+28
-11
@@ -25,14 +25,28 @@ class CompilerArgumentParsingTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("parameters")
|
||||
fun `test - parsing random compiler arguments`(type: KClass<out CommonToolArguments>, seed: Int, useShortNames: Boolean) {
|
||||
fun `test - parsing random compiler arguments`(
|
||||
type: KClass<out CommonToolArguments>,
|
||||
seed: Int,
|
||||
shortArgumentKeys: Boolean,
|
||||
compactArgumentValues: Boolean
|
||||
) {
|
||||
val constructor = type.constructors.find { it.parameters.isEmpty() } ?: error("Missing empty constructor on $type")
|
||||
val arguments = constructor.call()
|
||||
arguments.fillRandomValues(Random(seed))
|
||||
val argumentsAsStrings = arguments.toArgumentStrings(useShortNames)
|
||||
val argumentsAsStrings = arguments.toArgumentStrings(
|
||||
shortArgumentKeys = shortArgumentKeys,
|
||||
compactArgumentValues = compactArgumentValues
|
||||
)
|
||||
val parsedArguments = parseCommandLineArguments(type, argumentsAsStrings)
|
||||
assertEqualArguments(arguments, parsedArguments)
|
||||
assertEquals(argumentsAsStrings, parsedArguments.toArgumentStrings(useShortNames))
|
||||
assertEquals(
|
||||
argumentsAsStrings,
|
||||
parsedArguments.toArgumentStrings(
|
||||
shortArgumentKeys = shortArgumentKeys,
|
||||
compactArgumentValues = compactArgumentValues
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -40,12 +54,15 @@ class CompilerArgumentParsingTest {
|
||||
fun parameters(): List<Arguments> = getCompilerArgumentImplementations()
|
||||
.flatMap { clazz ->
|
||||
listOf(1002, 2803, 2411).flatMap { seed ->
|
||||
listOf(true, false).map { useShortNames ->
|
||||
Arguments.of(
|
||||
Named.of("${clazz.simpleName}", clazz),
|
||||
Named.of("seed: $seed", seed),
|
||||
Named.of("useShortNames: $useShortNames", useShortNames)
|
||||
)
|
||||
listOf(true, false).flatMap { shortArgumentKeys ->
|
||||
listOf(true, false).map { compactArgumentValues ->
|
||||
Arguments.of(
|
||||
Named.of("${clazz.simpleName}", clazz),
|
||||
Named.of("seed: $seed", seed),
|
||||
Named.of("shortArgumentKeys: $shortArgumentKeys", shortArgumentKeys),
|
||||
Named.of("compactArgumentValues: $compactArgumentValues", compactArgumentValues)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,14 +113,14 @@ private fun Random.randomString() = nextBytes(nextInt(8, 12)).let { data ->
|
||||
private fun Random.randomBoolean() = nextBoolean()
|
||||
|
||||
private fun Random.randomStringArray(): Array<String> {
|
||||
val size = nextInt(1, 5)
|
||||
val size = nextInt(5, 10)
|
||||
return Array(size) {
|
||||
randomString()
|
||||
}
|
||||
}
|
||||
|
||||
private fun Random.randomList(elementType: KType): List<Any>? {
|
||||
val size = nextInt(1, 5)
|
||||
val size = nextInt(5, 10)
|
||||
return List(size) {
|
||||
randomValue(elementType) ?: return null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user