ValuePluginDataCodegen.kt 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * Copyright 2019-2022 Mamoe Technologies and contributors.
  3. *
  4. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  5. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
  6. *
  7. * https://github.com/mamoe/mirai/blob/dev/LICENSE
  8. */
  9. @file:Suppress("PRE_RELEASE_CLASS", "ClassName", "RedundantVisibilityModifier", "KDocUnresolvedReference")
  10. package net.mamoe.mirai.console.codegen
  11. import kotlin.reflect.full.functions
  12. import kotlin.reflect.full.hasAnnotation
  13. import kotlin.reflect.full.isSubclassOf
  14. internal object ValuePluginDataCodegen {
  15. /**
  16. * The interface
  17. */
  18. object PrimitiveValuesCodegen : RegionCodegen("Value.kt"), DefaultInvoke {
  19. @JvmStatic
  20. fun main(args: Array<String>) = super.startIndependently()
  21. override val defaultInvokeArgs: List<KtType> = KtPrimitives + KtString
  22. override fun StringBuilder.apply(ktType: KtType) {
  23. @Suppress("ClassName")
  24. appendKCode(
  25. """
  26. /**
  27. * 表示一个不可空 [$ktType] [Value].
  28. */
  29. public interface ${ktType}Value : PrimitiveValue<$ktType>
  30. """
  31. )
  32. }
  33. }
  34. object BuiltInSerializerConstantsPrimitivesCodegen : RegionCodegen("_PluginData.value.kt"), DefaultInvoke {
  35. @JvmStatic
  36. fun main(args: Array<String>) = super.startIndependently()
  37. override val defaultInvokeArgs: List<KtType> = KtPrimitives + KtString
  38. override fun StringBuilder.apply(ktType: KtType) {
  39. appendLine(
  40. kCode(
  41. """
  42. @JvmStatic
  43. internal val ${ktType.standardName}SerializerDescriptor = ${ktType.standardName}.serializer().descriptor
  44. """
  45. ).lines().joinToString("\n") { " $it" }
  46. )
  47. }
  48. }
  49. object PrimitiveValuesImplCodegen : RegionCodegen("_PrimitiveValueDeclarations.kt"), DefaultInvoke {
  50. @JvmStatic
  51. fun main(args: Array<String>) = super.startIndependently()
  52. override val defaultInvokeArgs: List<KtType> = KtPrimitives + KtString
  53. override fun StringBuilder.apply(ktType: KtType) {
  54. appendKCode(
  55. """
  56. internal abstract class ${ktType.standardName}ValueImpl : ${ktType.standardName}Value, SerializerAwareValue<${ktType.standardName}>, KSerializer<Unit>, AbstractValueImpl<${ktType.standardName}> {
  57. constructor()
  58. constructor(default: ${ktType.standardName}) {
  59. _value = default
  60. }
  61. private var _value: ${ktType.standardName}? = null
  62. final override var value: ${ktType.standardName}
  63. get() = _value ?: error("${ktType.standardName}Value.value should be initialized before get.")
  64. set(v) {
  65. if (v != this._value) {
  66. if (this._value == null) {
  67. this._value = v
  68. } else {
  69. this._value = v
  70. onChanged()
  71. }
  72. }
  73. }
  74. protected abstract fun onChanged()
  75. final override val serializer: KSerializer<Unit> get() = this
  76. final override val descriptor: SerialDescriptor get() = BuiltInSerializerConstants.${ktType.standardName}SerializerDescriptor
  77. final override fun serialize(encoder: Encoder, value: Unit) = ${ktType.standardName}.serializer().serialize(encoder, this.value)
  78. final override fun deserialize(decoder: Decoder) = setValueBySerializer(${ktType.standardName}.serializer().deserialize(decoder))
  79. override fun toString(): String = _value${if (ktType != KtString) "?.toString()" else ""} ?: "${ktType.standardName}Value.value not yet initialized."
  80. override fun equals(other: Any?): Boolean = other is ${ktType.standardName}ValueImpl && other::class.java == this::class.java && other._value == this._value
  81. override fun hashCode(): Int {
  82. val value = _value
  83. return if (value == null) 1
  84. else value.hashCode() * 31
  85. }
  86. }
  87. """
  88. )
  89. }
  90. }
  91. object PluginData_value_PrimitivesImplCodegen : RegionCodegen("_PluginData.value.kt"), DefaultInvoke {
  92. @JvmStatic
  93. fun main(args: Array<String>) = super.startIndependently()
  94. override val defaultInvokeArgs: List<KtType> = KtPrimitives + KtString
  95. override fun StringBuilder.apply(ktType: KtType) {
  96. appendKCode(
  97. """
  98. internal fun PluginData.valueImpl(default: ${ktType.standardName}): SerializerAwareValue<${ktType.standardName}> {
  99. return object : ${ktType.standardName}ValueImpl(default) {
  100. override fun onChanged() = [email protected](this)
  101. }
  102. }
  103. internal fun PluginData.${ktType.lowerCaseName}ValueImpl(): SerializerAwareValue<${ktType.standardName}> {
  104. return object : ${ktType.standardName}ValueImpl() {
  105. override fun onChanged() = this@${ktType.lowerCaseName}ValueImpl.onValueChanged(this)
  106. }
  107. }
  108. """
  109. )
  110. }
  111. }
  112. object PluginData_valueImplPrimitiveCodegen : RegionCodegen("_PluginData.value.kt"), DefaultInvoke {
  113. @JvmStatic
  114. fun main(args: Array<String>) = super.startIndependently()
  115. override val defaultInvokeArgs: List<KtType> = KtPrimitives + KtString
  116. override fun StringBuilder.apply(ktType: KtType) {
  117. appendKCode(
  118. """
  119. ${ktType.standardName}::class -> ${ktType.lowerCaseName}ValueImpl()
  120. """.trimIndent()
  121. )
  122. }
  123. }
  124. object PluginData_value_primitivesCodegen : RegionCodegen("PluginData.kt"), DefaultInvoke {
  125. @JvmStatic
  126. fun main(args: Array<String>) = super.startIndependently()
  127. override val defaultInvokeArgs: List<KtType> = KtPrimitives + KtString
  128. override fun StringBuilder.apply(ktType: KtType) {
  129. @Suppress("unused")
  130. appendKCode(
  131. """
  132. /**
  133. * 创建一个 [${ktType.standardName}] 类型的 [Value], 并设置初始值为 [default]
  134. */
  135. public fun PluginData.value(default: ${ktType.standardName}): SerializerAwareValue<${ktType.standardName}> = valueImpl(default)
  136. """
  137. )
  138. appendLine()
  139. }
  140. }
  141. object JPluginData_value_primitivesCodegen : RegionCodegen("JAutoSavePluginData.kt"), DefaultInvoke {
  142. @JvmStatic
  143. fun main(args: Array<String>) = super.startIndependently()
  144. override val defaultInvokeArgs: List<KtType> = KtPrimitives + KtString
  145. override fun StringBuilder.apply(ktType: KtType) {
  146. @Suppress("unused")
  147. appendKCode(
  148. """
  149. /**
  150. * 创建一个 [${ktType.standardName}] 类型的 [Value], 并设置初始值为 [default]
  151. */
  152. public fun value(default: ${ktType.standardName}): SerializerAwareValue<${ktType.standardName}> = valueImpl(default)
  153. """
  154. )
  155. appendLine()
  156. }
  157. }
  158. /**
  159. * @since 2.11
  160. */
  161. object JavaAutoSavePluginData_value_primitivesCodegen : RegionCodegen("JavaAutoSavePluginData.kt"), DefaultInvoke {
  162. @JvmStatic
  163. fun main(args: Array<String>) = super.startIndependently()
  164. override val defaultInvokeArgs: List<KtType> = KtPrimitives + KtString
  165. override fun StringBuilder.apply(ktType: KtType) {
  166. @Suppress("unused")
  167. appendKCode(
  168. """
  169. /**
  170. * 创建一个名称为 [name], 类型为 [${ktType.standardName}] 的 [Value], 并设置初始值为 [default].
  171. */
  172. public fun value(name: String, default: ${ktType.standardName}): SerializerAwareValue<${ktType.standardName}> = valueImpl(default).apply { track(this, name, emptyList()) }
  173. """
  174. )
  175. appendLine()
  176. }
  177. }
  178. /**
  179. * 运行本 object 中所有嵌套 object Codegen
  180. */
  181. @OptIn(ExperimentalStdlibApi::class)
  182. @JvmStatic
  183. fun main(args: Array<String>) {
  184. ValuePluginDataCodegen::class.nestedClasses
  185. .filter { it.isSubclassOf(RegionCodegen::class) }
  186. .associateWith { kClass -> kClass.functions.find { it.name == "main" && it.hasAnnotation<JvmStatic>() } }
  187. .filter { it.value != null }
  188. .forEach { (kClass, entryPoint) ->
  189. println("---------------------------------------------")
  190. println("Running Codegen: ${kClass.simpleName}")
  191. entryPoint!!.call(kClass.objectInstance, arrayOf<String>())
  192. println("---------------------------------------------")
  193. }
  194. }
  195. }