mirror of
https://github.com/HighCapable/SweetProperty.git
synced 2025-09-04 01:35:37 +08:00
fix: special or repeat chars cause code generation failed
This commit is contained in:
@@ -27,6 +27,7 @@ import com.highcapable.sweetproperty.plugin.config.proxy.ISweetPropertyConfigs
|
||||
import com.highcapable.sweetproperty.plugin.extension.accessors.proxy.IExtensionAccessors
|
||||
import com.highcapable.sweetproperty.plugin.generator.factory.PropertyMap
|
||||
import com.highcapable.sweetproperty.plugin.generator.factory.parseTypedValue
|
||||
import com.highcapable.sweetproperty.plugin.generator.factory.toOptimize
|
||||
import com.highcapable.sweetproperty.utils.capitalize
|
||||
import com.highcapable.sweetproperty.utils.debug.SError
|
||||
import com.highcapable.sweetproperty.utils.firstNumberToLetter
|
||||
@@ -255,9 +256,10 @@ internal class PropertiesAccessorsGenerator {
|
||||
*
|
||||
* 解析完成后需要调用 [releaseParseTypeSpec] 完成解析
|
||||
* @param successiveName 连续的名称
|
||||
* @param key 键值名称 (原始名称)
|
||||
* @param value 键值内容
|
||||
*/
|
||||
private fun parseTypeSpec(successiveName: String, value: Any) {
|
||||
private fun parseTypeSpec(successiveName: String, key: String, value: Any) {
|
||||
/**
|
||||
* 获取生成的属性键值连续名称重复次数
|
||||
* @return [Int]
|
||||
@@ -279,10 +281,7 @@ internal class PropertiesAccessorsGenerator {
|
||||
var grandAcccessorsName = ""
|
||||
var grandSuccessiveName = ""
|
||||
val successiveNames = mutableListOf<Triple<String, String, String>>()
|
||||
val splitNames = replace(".", "|").replace("-", "|")
|
||||
.replace("_", "|").replace(" ", "_")
|
||||
.split("|").dropWhile { it.isBlank() }
|
||||
.ifEmpty { listOf(this) }
|
||||
val splitNames = split("_").dropWhile { it.isBlank() }.ifEmpty { listOf(this) }
|
||||
splitNames.forEach { eachName ->
|
||||
val name = eachName.capitalize().toNonJavaName().firstNumberToLetter()
|
||||
grandAcccessorsName += if (grandAcccessorsName.isNotBlank()) ".$eachName" else eachName
|
||||
@@ -303,7 +302,7 @@ internal class PropertiesAccessorsGenerator {
|
||||
val lastClassName = lastItem?.second ?: ""
|
||||
val lastMethodName = lastItem?.third ?: ""
|
||||
val isPreLastIndex = index == successiveNames.lastIndex - 1
|
||||
if (successiveNames.size == 1) getOrCreateClassSpec(TOP_SUCCESSIVE_NAME).addFinalValueMethod(successiveName, methodName, className, value)
|
||||
if (successiveNames.size == 1) getOrCreateClassSpec(TOP_SUCCESSIVE_NAME).addFinalValueMethod(key, methodName, className, value)
|
||||
if (index == successiveNames.lastIndex) return@forEachIndexed
|
||||
if (index == 0) noRepeated(TOP_SUCCESSIVE_NAME, methodName, className) {
|
||||
getOrCreateClassSpec(TOP_SUCCESSIVE_NAME, accessorsName)
|
||||
@@ -316,7 +315,7 @@ internal class PropertiesAccessorsGenerator {
|
||||
if (!isPreLastIndex) {
|
||||
addSuccessiveField(nextAccessorsName, nextClassName)
|
||||
addSuccessiveMethod(nextAccessorsName, nextMethodName, nextClassName)
|
||||
} else addFinalValueMethod(successiveName, lastMethodName, lastClassName, value)
|
||||
} else addFinalValueMethod(key, lastMethodName, lastClassName, value)
|
||||
}
|
||||
if (!isPreLastIndex) preAddConstructorSpecNames.add(className to nextClassName)
|
||||
}
|
||||
@@ -390,8 +389,8 @@ internal class PropertiesAccessorsGenerator {
|
||||
val keyValues = allKeyValues[index]
|
||||
clearGeneratedData()
|
||||
createTopClassSpec(configs)
|
||||
keyValues.forEach { (key, value) ->
|
||||
parseTypeSpec(key, value)
|
||||
keyValues.toOptimize().forEach { (key, value) ->
|
||||
parseTypeSpec(key, value.first, value.second)
|
||||
releaseParseTypeSpec()
|
||||
}; files.add(buildTypeSpec().createJavaFile(ACCESSORS_PACKAGE_NAME))
|
||||
}; files
|
||||
|
@@ -25,9 +25,10 @@ import com.highcapable.sweetproperty.SweetProperty
|
||||
import com.highcapable.sweetproperty.plugin.config.proxy.ISweetPropertyConfigs
|
||||
import com.highcapable.sweetproperty.plugin.generator.factory.PropertyMap
|
||||
import com.highcapable.sweetproperty.plugin.generator.factory.parseTypedValue
|
||||
import com.highcapable.sweetproperty.plugin.generator.factory.toOptimize
|
||||
import com.highcapable.sweetproperty.plugin.generator.factory.toUnderscores
|
||||
import com.highcapable.sweetproperty.utils.debug.SError
|
||||
import com.highcapable.sweetproperty.utils.firstNumberToLetter
|
||||
import com.highcapable.sweetproperty.utils.underscore
|
||||
import com.squareup.kotlinpoet.FileSpec
|
||||
import com.squareup.kotlinpoet.KModifier
|
||||
import com.squareup.kotlinpoet.PropertySpec
|
||||
@@ -67,13 +68,13 @@ internal class PropertiesSourcesGenerator {
|
||||
""".trimIndent()
|
||||
)
|
||||
if (configs.isEnableRestrictedAccess) addModifiers(KModifier.INTERNAL)
|
||||
keyValues.forEach { (key, value) ->
|
||||
val typedValue = value.parseTypedValue(configs.isEnableTypeAutoConversion)
|
||||
addProperty(PropertySpec.builder(key.firstNumberToLetter().underscore(), typedValue.first).apply {
|
||||
addKdoc("Resolve the \"$key\" value ${typedValue.second}")
|
||||
keyValues.toOptimize().toUnderscores().forEach { (key, value) ->
|
||||
val typedValue = value.second.parseTypedValue(configs.isEnableTypeAutoConversion)
|
||||
addProperty(PropertySpec.builder(key.firstNumberToLetter(), typedValue.first).apply {
|
||||
addKdoc("Resolve the \"${value.first.toKotlinPoetNoEscape()}\" value ${typedValue.second.toKotlinPoetNoEscape()}")
|
||||
if (configs.isEnableRestrictedAccess) addModifiers(KModifier.INTERNAL)
|
||||
addModifiers(KModifier.CONST)
|
||||
initializer(typedValue.second.toKotlinPoetSpace())
|
||||
initializer(typedValue.second.toKotlinPoetNoEscape().toKotlinPoetSpace())
|
||||
}.build())
|
||||
}
|
||||
}.build())
|
||||
@@ -85,4 +86,10 @@ internal class PropertiesSourcesGenerator {
|
||||
* @return [String]
|
||||
*/
|
||||
private fun String.toKotlinPoetSpace() = replace(" ", "·")
|
||||
|
||||
/**
|
||||
* 转换到 KotlinPoet 非转义字符内容
|
||||
* @return [String]
|
||||
*/
|
||||
private fun String.toKotlinPoetNoEscape() = replace("%", "%%")
|
||||
}
|
@@ -21,11 +21,15 @@
|
||||
*/
|
||||
package com.highcapable.sweetproperty.plugin.generator.factory
|
||||
|
||||
import com.highcapable.sweetproperty.utils.underscore
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/** 属性键值数组类型定义 */
|
||||
internal typealias PropertyMap = MutableMap<String, Any>
|
||||
|
||||
/** 属性键值优化数组类型定义 */
|
||||
internal typealias PropertyOptimizeMap = MutableMap<String, Pair<String, Any>>
|
||||
|
||||
/** 属性键值规则类型定义 */
|
||||
internal typealias PropertyValueRule = (value: String) -> String
|
||||
|
||||
@@ -64,4 +68,34 @@ internal fun Any.parseTypedValue(isAutoConversion: Boolean): Pair<KClass<*>, Str
|
||||
}; return Pair(typeSpec, if (typeSpec == String::class) "\"$valueString\"" else valueString.let {
|
||||
if (typeSpec == Long::class && !it.endsWith("L")) "${it}L" else it
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* [PropertyMap] 转换到 [PropertyOptimizeMap]
|
||||
*
|
||||
* 替换可能的键值名称特殊字符内容并保留原始键值名称
|
||||
* @return [PropertyOptimizeMap]
|
||||
*/
|
||||
internal fun PropertyMap.toOptimize(): PropertyOptimizeMap {
|
||||
val newMap: PropertyOptimizeMap = mutableMapOf()
|
||||
var uniqueNumber = 1
|
||||
forEach { (key, value) ->
|
||||
var newKey = key.replace("\\W".toRegex(), "_")
|
||||
while (newMap.containsKey(newKey)) newKey = "$newKey${++uniqueNumber}"
|
||||
newMap[newKey] = key to value
|
||||
}; return newMap
|
||||
}
|
||||
|
||||
/**
|
||||
* [PropertyOptimizeMap] 转换为大写下划线命名
|
||||
* @return [PropertyOptimizeMap]
|
||||
*/
|
||||
internal fun PropertyOptimizeMap.toUnderscores(): PropertyOptimizeMap {
|
||||
val newMap: PropertyOptimizeMap = mutableMapOf()
|
||||
var uniqueNumber = 1
|
||||
forEach { (key, value) ->
|
||||
var newKey = key.underscore()
|
||||
while (newMap.containsKey(newKey)) newKey = "$newKey${++uniqueNumber}"
|
||||
newMap[newKey] = value.first to value.second
|
||||
}; return newMap
|
||||
}
|
Reference in New Issue
Block a user