mirror of
https://github.com/HighCapable/Gropify.git
synced 2025-12-10 15:24:07 +08:00
feat: add expected type class feature in ValueRule for keyValuesRules
This commit is contained in:
@@ -106,7 +106,9 @@ internal object DefaultDeployer {
|
||||
val properties = mutableMapOf<String, PropertyTypeValue>()
|
||||
val resolveProperties = mutableMapOf<Any?, Any?>()
|
||||
|
||||
config.permanentKeyValues.forEach { (key, value) -> properties[key] = value.createTypeValueByType(config.useTypeAutoConversion) }
|
||||
config.permanentKeyValues.forEach { (key, value) ->
|
||||
properties[key] = value.createTypeValueByType(config.useTypeAutoConversion, key)
|
||||
}
|
||||
config.locations.forEach { location ->
|
||||
when (location) {
|
||||
GropifyLocation.CurrentProject -> createProperties(config, descriptor.currentDir).forEach { resolveProperties.putAll(it) }
|
||||
@@ -136,7 +138,7 @@ internal object DefaultDeployer {
|
||||
}
|
||||
} ?: true
|
||||
}.toMutableMap().also { resolveKeyValues ->
|
||||
resolveKeyValues.onEach { (key, value) ->
|
||||
resolveKeyValues.forEach { (key, value) ->
|
||||
val resolveKeys = mutableListOf<String>()
|
||||
|
||||
fun String.resolveValue(): String = replaceInterpolation { matchKey ->
|
||||
@@ -155,17 +157,25 @@ internal object DefaultDeployer {
|
||||
}
|
||||
|
||||
if (value.hasInterpolation()) resolveKeyValues[key] = value.resolveValue()
|
||||
}.takeIf { config.keyValuesRules.isNotEmpty() }?.forEach { (key, value) ->
|
||||
config.keyValuesRules[key]?.also { resolveKeyValues[key] = it(value) }
|
||||
}
|
||||
|
||||
properties.putAll(resolveKeyValues.map { (key, value) ->
|
||||
key to value.createTypeValue(config.useTypeAutoConversion)
|
||||
key to value.createTypeValue(config.useTypeAutoConversion, key)
|
||||
})
|
||||
}
|
||||
|
||||
// Replace all key-values if exists.
|
||||
config.replacementKeyValues.forEach { (key, value) -> properties[key] = value.createTypeValueByType(config.useTypeAutoConversion) }
|
||||
config.replacementKeyValues.forEach { (key, value) ->
|
||||
properties[key] = value.createTypeValueByType(config.useTypeAutoConversion, key)
|
||||
}
|
||||
|
||||
// Apply key-values rules.
|
||||
properties.forEach { (key, value) ->
|
||||
val (mapper, type) = config.keyValuesRules[key] ?: return@forEach
|
||||
|
||||
val resolveValue = mapper(value.raw).createTypeValue(config.useTypeAutoConversion, key, type)
|
||||
properties[key] = resolveValue
|
||||
}
|
||||
|
||||
return properties
|
||||
}
|
||||
|
||||
@@ -30,11 +30,13 @@ import com.highcapable.gropify.plugin.Gropify
|
||||
import com.highcapable.gropify.plugin.config.extension.create
|
||||
import com.highcapable.gropify.plugin.config.proxy.GropifyConfig
|
||||
import com.highcapable.gropify.plugin.config.type.GropifyLocation
|
||||
import com.highcapable.gropify.plugin.generator.extension.PropertyValueMapper
|
||||
import com.highcapable.gropify.plugin.generator.extension.PropertyValueRule
|
||||
import com.highcapable.gropify.utils.KeywordsDetector
|
||||
import com.highcapable.gropify.utils.extension.isStartsWithLetter
|
||||
import org.gradle.api.Action
|
||||
import org.gradle.api.initialization.Settings
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Configure extension for Gropify.
|
||||
@@ -447,8 +449,13 @@ open class GropifyConfigureExtension internal constructor() {
|
||||
*
|
||||
* ```kotlin
|
||||
* keyValuesRules(
|
||||
* "some.key1" to createValueRule { if (it.contains("_")) it.replace("_", "-") else it },
|
||||
* "some.key2" to createValueRule { "$it-value" }
|
||||
* "some.key1" to ValueRule { if (it.contains("_")) it.replace("_", "-") else it },
|
||||
* "some.key2" to ValueRule { "$it-value" },
|
||||
* // You can also specify the expected type class,
|
||||
* // the type you specify will be used during generation,
|
||||
* // and an exception will be thrown if the type cannot be converted correctly.
|
||||
* // If the [useTypeAutoConversion] is not enabled, this parameter will be ignored.
|
||||
* "some.key3" to ValueRule(Int::class)
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
@@ -483,10 +490,13 @@ open class GropifyConfigureExtension internal constructor() {
|
||||
|
||||
/**
|
||||
* Create a new properties' values rule.
|
||||
* @param type specify the expected type class, or null to auto-detect,
|
||||
* if the [useTypeAutoConversion] is not enabled, this parameter will be ignored.
|
||||
* @param rule callback current rule.
|
||||
* @return [PropertyValueRule]
|
||||
*/
|
||||
fun ValueRule(rule: PropertyValueRule) = rule
|
||||
@JvmOverloads
|
||||
fun ValueRule(type: KClass<*>? = null, rule: PropertyValueMapper = { it }) = rule to type
|
||||
|
||||
/**
|
||||
* Set where to find properties' key-values.
|
||||
|
||||
@@ -22,10 +22,12 @@
|
||||
package com.highcapable.gropify.plugin.generator.extension
|
||||
|
||||
import com.highcapable.gropify.utils.extension.underscore
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
internal typealias PropertyMap = MutableMap<String, PropertyTypeValue>
|
||||
internal typealias PropertyOptimizeMap = MutableMap<String, Pair<String, PropertyTypeValue>>
|
||||
internal typealias PropertyValueRule = (value: String) -> String
|
||||
internal typealias PropertyValueMapper = (value: String) -> String
|
||||
internal typealias PropertyValueRule = Pair<PropertyValueMapper, KClass<*>?>
|
||||
|
||||
/**
|
||||
* Optimize property keys for code generation.
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
package com.highcapable.gropify.plugin.generator.extension
|
||||
|
||||
import com.highcapable.gropify.internal.error
|
||||
import com.highcapable.gropify.internal.require
|
||||
import com.highcapable.gropify.plugin.Gropify
|
||||
import com.highcapable.gropify.utils.extension.isNumeric
|
||||
import kotlin.reflect.KClass
|
||||
@@ -30,9 +31,12 @@ import kotlin.reflect.KClass
|
||||
* Create [PropertyTypeValue] from [String] value.
|
||||
* @receiver [String]
|
||||
* @param autoConversion whether to enable auto conversion.
|
||||
* @param key the property key name.
|
||||
* @param type specify the expected type class, or null to auto-detect,
|
||||
* if the [autoConversion] is not `true`, this parameter will be ignored.
|
||||
* @return [PropertyTypeValue]
|
||||
*/
|
||||
internal fun String.createTypeValue(autoConversion: Boolean): PropertyTypeValue {
|
||||
internal fun String.createTypeValue(autoConversion: Boolean, key: String, type: KClass<*>? = null): PropertyTypeValue {
|
||||
var isStringType = false
|
||||
val valueString = replace("\n", "\\n")
|
||||
.replace("\r", "\\r")
|
||||
@@ -47,6 +51,56 @@ internal fun String.createTypeValue(autoConversion: Boolean): PropertyTypeValue
|
||||
if (!autoConversion) return PropertyTypeValue(this, "\"$valueString\"", String::class)
|
||||
|
||||
val trimmed = valueString.trim()
|
||||
|
||||
if (type != null) {
|
||||
val finalValue = when (type) {
|
||||
String::class -> "\"$valueString\""
|
||||
CharSequence::class -> "\"$valueString\""
|
||||
Char::class -> trimmed.firstOrNull()?.let { "'$it'" }
|
||||
?: Gropify.error("The \"$key\" value is empty and cannot be converted to Char type.")
|
||||
Boolean::class -> if (trimmed.toBooleanStrictOrNull() != null)
|
||||
trimmed
|
||||
else ((trimmed.toIntOrNull() ?: 0) > 0).toString()
|
||||
Int::class -> {
|
||||
val intValue = trimmed.toIntOrNull()
|
||||
Gropify.require(intValue != null && intValue in Int.MIN_VALUE..Int.MAX_VALUE) {
|
||||
"The \"$key\" value \"$this\" cannot be converted to Int type."
|
||||
}
|
||||
|
||||
trimmed
|
||||
}
|
||||
Long::class -> {
|
||||
Gropify.require(trimmed.toLongOrNull() != null) {
|
||||
"The \"$key\" value \"$this\" cannot be converted to Long type."
|
||||
}
|
||||
|
||||
if (trimmed.endsWith("L")) trimmed else "${trimmed}L"
|
||||
}
|
||||
Double::class -> {
|
||||
val doubleValue = trimmed.toDoubleOrNull()
|
||||
Gropify.require(doubleValue != null && !doubleValue.isInfinite()) {
|
||||
"The \"$key\" value \"$this\" cannot be converted to Double type."
|
||||
}
|
||||
|
||||
trimmed
|
||||
}
|
||||
Float::class -> {
|
||||
val floatValue = trimmed.toFloatOrNull()
|
||||
Gropify.require(floatValue != null && !floatValue.isInfinite()) {
|
||||
"The \"$key\" value \"$this\" cannot be converted to Float type."
|
||||
}
|
||||
|
||||
if (trimmed.endsWith("f") || trimmed.endsWith("F")) trimmed else "${trimmed}f"
|
||||
}
|
||||
else -> Gropify.error(
|
||||
"Unsupported property \"$key\" value type: ${type.qualifiedName}, " +
|
||||
"only String, CharSequence, Char, Boolean, Int, Long, Float, Double are supported."
|
||||
)
|
||||
}
|
||||
|
||||
return PropertyTypeValue(this, finalValue, type)
|
||||
}
|
||||
|
||||
val typeSpec = when {
|
||||
isStringType -> String::class
|
||||
trimmed.toBooleanStrictOrNull() != null -> Boolean::class
|
||||
@@ -79,9 +133,10 @@ internal fun String.createTypeValue(autoConversion: Boolean): PropertyTypeValue
|
||||
* Create [PropertyTypeValue] from [Any] value's type.
|
||||
* @receiver [Any]
|
||||
* @param autoConversion whether to enable auto conversion.
|
||||
* @param key the property key name.
|
||||
* @return [PropertyTypeValue]
|
||||
*/
|
||||
internal fun Any.createTypeValueByType(autoConversion: Boolean): PropertyTypeValue {
|
||||
internal fun Any.createTypeValueByType(autoConversion: Boolean, key: String): PropertyTypeValue {
|
||||
val typeSpec = this.javaClass.kotlin
|
||||
val valueString = toString()
|
||||
.replace("\n", "\\n")
|
||||
@@ -94,12 +149,13 @@ internal fun Any.createTypeValueByType(autoConversion: Boolean): PropertyTypeVal
|
||||
val finalValue = if (autoConversion) when (typeSpec) {
|
||||
String::class, CharSequence::class -> "\"$trimmed\""
|
||||
Char::class -> "'$trimmed'"
|
||||
Boolean::class -> trimmed
|
||||
Long::class -> if (trimmed.endsWith("L")) trimmed else "${trimmed}L"
|
||||
Float::class -> if (trimmed.endsWith("f") || trimmed.endsWith("F")) trimmed else "${trimmed}f"
|
||||
Int::class, Double::class -> trimmed
|
||||
else -> Gropify.error(
|
||||
"Unsupported property value type: ${typeSpec.qualifiedName}, " +
|
||||
"only String, CharSequence, Char, Int, Long, Float, Double are supported."
|
||||
"Unsupported property \"$key\" value type: ${typeSpec.qualifiedName}, " +
|
||||
"only String, CharSequence, Char, Boolean, Int, Long, Float, Double are supported."
|
||||
)
|
||||
} else "\"$valueString\""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user