fix: special or repeat chars cause code generation failed

This commit is contained in:
2023-11-08 14:50:49 +08:00
parent 5d5c3af69a
commit 93c8107e76
3 changed files with 55 additions and 15 deletions

View File

@@ -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.extension.accessors.proxy.IExtensionAccessors
import com.highcapable.sweetproperty.plugin.generator.factory.PropertyMap import com.highcapable.sweetproperty.plugin.generator.factory.PropertyMap
import com.highcapable.sweetproperty.plugin.generator.factory.parseTypedValue 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.capitalize
import com.highcapable.sweetproperty.utils.debug.SError import com.highcapable.sweetproperty.utils.debug.SError
import com.highcapable.sweetproperty.utils.firstNumberToLetter import com.highcapable.sweetproperty.utils.firstNumberToLetter
@@ -255,9 +256,10 @@ internal class PropertiesAccessorsGenerator {
* *
* 解析完成后需要调用 [releaseParseTypeSpec] 完成解析 * 解析完成后需要调用 [releaseParseTypeSpec] 完成解析
* @param successiveName 连续的名称 * @param successiveName 连续的名称
* @param key 键值名称 (原始名称)
* @param value 键值内容 * @param value 键值内容
*/ */
private fun parseTypeSpec(successiveName: String, value: Any) { private fun parseTypeSpec(successiveName: String, key: String, value: Any) {
/** /**
* 获取生成的属性键值连续名称重复次数 * 获取生成的属性键值连续名称重复次数
* @return [Int] * @return [Int]
@@ -279,10 +281,7 @@ internal class PropertiesAccessorsGenerator {
var grandAcccessorsName = "" var grandAcccessorsName = ""
var grandSuccessiveName = "" var grandSuccessiveName = ""
val successiveNames = mutableListOf<Triple<String, String, String>>() val successiveNames = mutableListOf<Triple<String, String, String>>()
val splitNames = replace(".", "|").replace("-", "|") val splitNames = split("_").dropWhile { it.isBlank() }.ifEmpty { listOf(this) }
.replace("_", "|").replace(" ", "_")
.split("|").dropWhile { it.isBlank() }
.ifEmpty { listOf(this) }
splitNames.forEach { eachName -> splitNames.forEach { eachName ->
val name = eachName.capitalize().toNonJavaName().firstNumberToLetter() val name = eachName.capitalize().toNonJavaName().firstNumberToLetter()
grandAcccessorsName += if (grandAcccessorsName.isNotBlank()) ".$eachName" else eachName grandAcccessorsName += if (grandAcccessorsName.isNotBlank()) ".$eachName" else eachName
@@ -303,7 +302,7 @@ internal class PropertiesAccessorsGenerator {
val lastClassName = lastItem?.second ?: "" val lastClassName = lastItem?.second ?: ""
val lastMethodName = lastItem?.third ?: "" val lastMethodName = lastItem?.third ?: ""
val isPreLastIndex = index == successiveNames.lastIndex - 1 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 == successiveNames.lastIndex) return@forEachIndexed
if (index == 0) noRepeated(TOP_SUCCESSIVE_NAME, methodName, className) { if (index == 0) noRepeated(TOP_SUCCESSIVE_NAME, methodName, className) {
getOrCreateClassSpec(TOP_SUCCESSIVE_NAME, accessorsName) getOrCreateClassSpec(TOP_SUCCESSIVE_NAME, accessorsName)
@@ -316,7 +315,7 @@ internal class PropertiesAccessorsGenerator {
if (!isPreLastIndex) { if (!isPreLastIndex) {
addSuccessiveField(nextAccessorsName, nextClassName) addSuccessiveField(nextAccessorsName, nextClassName)
addSuccessiveMethod(nextAccessorsName, nextMethodName, nextClassName) addSuccessiveMethod(nextAccessorsName, nextMethodName, nextClassName)
} else addFinalValueMethod(successiveName, lastMethodName, lastClassName, value) } else addFinalValueMethod(key, lastMethodName, lastClassName, value)
} }
if (!isPreLastIndex) preAddConstructorSpecNames.add(className to nextClassName) if (!isPreLastIndex) preAddConstructorSpecNames.add(className to nextClassName)
} }
@@ -390,8 +389,8 @@ internal class PropertiesAccessorsGenerator {
val keyValues = allKeyValues[index] val keyValues = allKeyValues[index]
clearGeneratedData() clearGeneratedData()
createTopClassSpec(configs) createTopClassSpec(configs)
keyValues.forEach { (key, value) -> keyValues.toOptimize().forEach { (key, value) ->
parseTypeSpec(key, value) parseTypeSpec(key, value.first, value.second)
releaseParseTypeSpec() releaseParseTypeSpec()
}; files.add(buildTypeSpec().createJavaFile(ACCESSORS_PACKAGE_NAME)) }; files.add(buildTypeSpec().createJavaFile(ACCESSORS_PACKAGE_NAME))
}; files }; files

View File

@@ -25,9 +25,10 @@ import com.highcapable.sweetproperty.SweetProperty
import com.highcapable.sweetproperty.plugin.config.proxy.ISweetPropertyConfigs import com.highcapable.sweetproperty.plugin.config.proxy.ISweetPropertyConfigs
import com.highcapable.sweetproperty.plugin.generator.factory.PropertyMap import com.highcapable.sweetproperty.plugin.generator.factory.PropertyMap
import com.highcapable.sweetproperty.plugin.generator.factory.parseTypedValue 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.debug.SError
import com.highcapable.sweetproperty.utils.firstNumberToLetter import com.highcapable.sweetproperty.utils.firstNumberToLetter
import com.highcapable.sweetproperty.utils.underscore
import com.squareup.kotlinpoet.FileSpec import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.KModifier import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.PropertySpec import com.squareup.kotlinpoet.PropertySpec
@@ -67,13 +68,13 @@ internal class PropertiesSourcesGenerator {
""".trimIndent() """.trimIndent()
) )
if (configs.isEnableRestrictedAccess) addModifiers(KModifier.INTERNAL) if (configs.isEnableRestrictedAccess) addModifiers(KModifier.INTERNAL)
keyValues.forEach { (key, value) -> keyValues.toOptimize().toUnderscores().forEach { (key, value) ->
val typedValue = value.parseTypedValue(configs.isEnableTypeAutoConversion) val typedValue = value.second.parseTypedValue(configs.isEnableTypeAutoConversion)
addProperty(PropertySpec.builder(key.firstNumberToLetter().underscore(), typedValue.first).apply { addProperty(PropertySpec.builder(key.firstNumberToLetter(), typedValue.first).apply {
addKdoc("Resolve the \"$key\" value ${typedValue.second}") addKdoc("Resolve the \"${value.first.toKotlinPoetNoEscape()}\" value ${typedValue.second.toKotlinPoetNoEscape()}")
if (configs.isEnableRestrictedAccess) addModifiers(KModifier.INTERNAL) if (configs.isEnableRestrictedAccess) addModifiers(KModifier.INTERNAL)
addModifiers(KModifier.CONST) addModifiers(KModifier.CONST)
initializer(typedValue.second.toKotlinPoetSpace()) initializer(typedValue.second.toKotlinPoetNoEscape().toKotlinPoetSpace())
}.build()) }.build())
} }
}.build()) }.build())
@@ -85,4 +86,10 @@ internal class PropertiesSourcesGenerator {
* @return [String] * @return [String]
*/ */
private fun String.toKotlinPoetSpace() = replace(" ", "·") private fun String.toKotlinPoetSpace() = replace(" ", "·")
/**
* 转换到 KotlinPoet 非转义字符内容
* @return [String]
*/
private fun String.toKotlinPoetNoEscape() = replace("%", "%%")
} }

View File

@@ -21,11 +21,15 @@
*/ */
package com.highcapable.sweetproperty.plugin.generator.factory package com.highcapable.sweetproperty.plugin.generator.factory
import com.highcapable.sweetproperty.utils.underscore
import kotlin.reflect.KClass import kotlin.reflect.KClass
/** 属性键值数组类型定义 */ /** 属性键值数组类型定义 */
internal typealias PropertyMap = MutableMap<String, Any> internal typealias PropertyMap = MutableMap<String, Any>
/** 属性键值优化数组类型定义 */
internal typealias PropertyOptimizeMap = MutableMap<String, Pair<String, Any>>
/** 属性键值规则类型定义 */ /** 属性键值规则类型定义 */
internal typealias PropertyValueRule = (value: String) -> String 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 { }; return Pair(typeSpec, if (typeSpec == String::class) "\"$valueString\"" else valueString.let {
if (typeSpec == Long::class && !it.endsWith("L")) "${it}L" else it 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
} }