From 70dd71cb61cc7decfc6861d01817983464011054 Mon Sep 17 00:00:00 2001 From: Him188 Date: Tue, 24 Mar 2020 13:42:33 +0800 Subject: [PATCH] Migrate to Kotlin 1.4 --- .../event/internal/InternalEventListeners.kt | 19 +--- .../kotlin/net.mamoe.mirai/event/select.kt | 8 +- .../event/subscribeMessages.kt | 86 +++++++++---------- .../net.mamoe.mirai/utils/contentToString.kt | 13 ++- 4 files changed, 56 insertions(+), 70 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt index 1f2480151..cd406b5ed 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt @@ -115,24 +115,9 @@ internal class Handler */ internal fun KClass.listeners(): EventListeners = EventListenerManager.get(this) -internal class EventListeners(clazz: KClass) : LockFreeLinkedList>() { +internal expect class EventListeners(clazz: KClass) : LockFreeLinkedList> { @Suppress("UNCHECKED_CAST", "UNSUPPORTED", "NO_REFLECTION_IN_CLASS_PATH") - val supertypes: Set> by lazy { - val supertypes = mutableSetOf>() - - fun addSupertypes(clazz: KClass) { - clazz.supertypes.forEach { - val classifier = it.classifier as? KClass - if (classifier != null) { - supertypes.add(classifier) - addSupertypes(classifier) - } - } - } - addSupertypes(clazz) - - supertypes - } + val supertypes: Set> } internal expect class MiraiAtomicBoolean(initial: Boolean) { diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/select.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/select.kt index 7b2e1f3fc..2fb90a21a 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/select.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/select.kt @@ -285,7 +285,7 @@ abstract class MessageSelectBuilderUnit, R> @PublishedAp * 在超时后引用回复原消息 * * 当 [block] 返回值为 [Unit] 时不回复, 为 [Message] 时回复 [Message], 其他将 [toString] 后回复为 [PlainText] - + * * @see timeout * @see reply */ @@ -304,8 +304,7 @@ abstract class MessageSelectBuilderUnit, R> @PublishedAp */ @MessageDsl fun defaultReply(block: suspend () -> Any?): Unit = subscriber({ true }, { - @Suppress("DSL_SCOPE_VIOLATION_WARNING") // false positive - executeAndReply(block) + this@MessageSelectBuilderUnit.executeAndReply(block) }) @@ -316,8 +315,7 @@ abstract class MessageSelectBuilderUnit, R> @PublishedAp */ @MessageDsl fun defaultQuoteReply(block: suspend () -> Any?): Unit = subscriber({ true }, { - @Suppress("DSL_SCOPE_VIOLATION_WARNING") // false positive - executeAndQuoteReply(block) + this@MessageSelectBuilderUnit.executeAndQuoteReply(block) }) private suspend inline fun executeAndReply(noinline block: suspend () -> Any?) { diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscribeMessages.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscribeMessages.kt index b29aac1eb..c143eea8d 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscribeMessages.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscribeMessages.kt @@ -262,7 +262,6 @@ typealias MessageListener = @MessageDsl suspend T.(String) -> R * @see subscribeFriendMessages * @sample demo.subscribe.messageDSL */ -// TODO: 2019/12/23 应定义为 inline, 但这会导致一个 JVM run-time VerifyError. 等待 kotlin 修复 bug (Kotlin 1.3.61) @Suppress("unused", "DSL_SCOPE_VIOLATION_WARNING") @MessageDsl open class MessageSubscribersBuilder, out Ret, R : RR, RR>( @@ -318,37 +317,36 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN) internal open infix fun reply(toReply: String): Ret { - return content(filter) { reply(toReply);stub } + return content(filter) { reply(toReply);this@MessageSubscribersBuilder.stub } } @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN) internal open infix fun reply(message: Message): Ret { - return content(filter) { reply(message);stub } + return content(filter) { reply(message);this@MessageSubscribersBuilder.stub } } @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN) internal open infix fun reply(replier: (@MessageDsl suspend M.(String) -> Any?)): Ret { return content(filter) { - @Suppress("DSL_SCOPE_VIOLATION_WARNING") - executeAndReply(replier) + this@MessageSubscribersBuilder.executeAndReply(this, replier) } } @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN) internal open infix fun quoteReply(toReply: String): Ret { - return content(filter) { quoteReply(toReply);stub } + return content(filter) { quoteReply(toReply);this@MessageSubscribersBuilder.stub } } @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN) internal open infix fun quoteReply(message: Message): Ret { - return content(filter) { quoteReply(message);stub } + return content(filter) { quoteReply(message);this@MessageSubscribersBuilder.stub } } @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN) internal open infix fun quoteReply(replier: (@MessageDsl suspend M.(String) -> Any?)): Ret { return content(filter) { @Suppress("DSL_SCOPE_VIOLATION_WARNING") - executeAndQuoteReply(replier) + this@MessageSubscribersBuilder.executeAndQuoteReply(this, replier) } } @@ -372,13 +370,13 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R @Suppress("EXTENSION_SHADOWED_BY_MEMBER") // binary compatibility @SinceMirai("0.29.0") open infix fun ListeningFilter.reply(toReply: String): Ret { - return content(filter) { reply(toReply);stub } + return content(filter) { reply(toReply);this@MessageSubscribersBuilder.stub } } @Suppress("EXTENSION_SHADOWED_BY_MEMBER") // binary compatibility @SinceMirai("0.29.0") open infix fun ListeningFilter.reply(message: Message): Ret { - return content(filter) { reply(message);stub } + return content(filter) { reply(message);this@MessageSubscribersBuilder.stub } } @Suppress("EXTENSION_SHADOWED_BY_MEMBER") // binary compatibility @@ -386,20 +384,20 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R open infix fun ListeningFilter.reply(replier: (@MessageDsl suspend M.(String) -> Any?)): Ret { return content(filter) { @Suppress("DSL_SCOPE_VIOLATION_WARNING") - executeAndReply(replier) + this@MessageSubscribersBuilder.executeAndReply(this, replier) } } @Suppress("EXTENSION_SHADOWED_BY_MEMBER") // binary compatibility @SinceMirai("0.29.0") open infix fun ListeningFilter.quoteReply(toReply: String): Ret { - return content(filter) { quoteReply(toReply);stub } + return content(filter) { quoteReply(toReply);this@MessageSubscribersBuilder.stub } } @Suppress("EXTENSION_SHADOWED_BY_MEMBER") // binary compatibility @SinceMirai("0.29.0") open infix fun ListeningFilter.quoteReply(message: Message): Ret { - return content(filter) { quoteReply(message);stub } + return content(filter) { quoteReply(message);this@MessageSubscribersBuilder.stub } } @Suppress("EXTENSION_SHADOWED_BY_MEMBER") // binary compatibility @@ -407,11 +405,10 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R open infix fun ListeningFilter.quoteReply(replier: (@MessageDsl suspend M.(String) -> Any?)): Ret { return content(filter) { @Suppress("DSL_SCOPE_VIOLATION_WARNING") - executeAndQuoteReply(replier) + this@MessageSubscribersBuilder.executeAndQuoteReply(this, replier) } } - // TODO: 2020/3/6 这些 lambda 都应该 crossinline, 但这会导致异常时的 stacktrace 不准确 (Kotlin 1.3.70) 待 Kotlin 修复此问题后恢复 inline 结构 /** * 无任何触发条件. @@ -753,7 +750,10 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R mapper: M.(String) -> N?, onEvent: @MessageDsl suspend M.(N) -> R ): Ret = always { - onEvent.invoke(this, mapper.invoke(this, message.toString()) ?: return@always stub) + onEvent.invoke( + this, + mapper.invoke(this, message.toString()) ?: return@always this@MessageSubscribersBuilder.stub + ) } /** @@ -781,16 +781,14 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R content { regex.matchEntire(it) != null } - // TODO: 2020/3/20 支持新泛型 /** * 如果消息内容可由正则表达式匹配([Regex.matchEntire]), 就执行 `onEvent` */ @MessageDsl fun matching(regex: Regex, onEvent: @MessageDsl suspend M.(MatchResult) -> Unit): Ret = always { - val find = regex.matchEntire(it) ?: return@always stub - @Suppress("DSL_SCOPE_VIOLATION_WARNING") - this.executeAndReply { + val find = regex.matchEntire(it) ?: return@always this@MessageSubscribersBuilder.stub + this@MessageSubscribersBuilder.executeAndReply(this) { onEvent.invoke(this, find) } } @@ -808,9 +806,8 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R @MessageDsl fun finding(regex: Regex, onEvent: @MessageDsl suspend M.(MatchResult) -> Unit): Ret = always { - val find = regex.find(it) ?: return@always stub - @Suppress("DSL_SCOPE_VIOLATION_WARNING") - this.executeAndReply { + val find = regex.find(it) ?: return@always this@MessageSubscribersBuilder.stub + this@MessageSubscribersBuilder.executeAndReply(this) { onEvent.invoke(this, find) } } @@ -821,7 +818,7 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R */ @MessageDsl open infix fun String.containsReply(reply: String): Ret = - content({ this@containsReply in it }, { reply(reply); stub }) + content({ this@containsReply in it }, { reply(reply); this@MessageSubscribersBuilder.stub }) /** * 若消息内容包含 [this] 则执行 [replier] 并将其返回值回复给发信对象. @@ -833,8 +830,7 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R @MessageDsl open infix fun String.containsReply(replier: @MessageDsl suspend M.(String) -> Any?): Ret = content({ this@containsReply in it }, { - @Suppress("DSL_SCOPE_VIOLATION_WARNING") - this.executeAndReply(replier) + this@MessageSubscribersBuilder.executeAndReply(this, replier) }) /** @@ -847,9 +843,8 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R @MessageDsl open infix fun Regex.matchingReply(replier: @MessageDsl suspend M.(MatchResult) -> Any?): Ret = always { - val find = this@matchingReply.matchEntire(it) ?: return@always stub - @Suppress("DSL_SCOPE_VIOLATION_WARNING") - this.executeAndReply { + val find = this@matchingReply.matchEntire(it) ?: return@always this@MessageSubscribersBuilder.stub + this@MessageSubscribersBuilder.executeAndReply(this) { replier.invoke(this, find) } } @@ -864,9 +859,8 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R @MessageDsl open infix fun Regex.findingReply(replier: @MessageDsl suspend M.(MatchResult) -> Any?): Ret = always { - val find = this@findingReply.find(it) ?: return@always stub - @Suppress("DSL_SCOPE_VIOLATION_WARNING") - this.executeAndReply { + val find = this@findingReply.find(it) ?: return@always this@MessageSubscribersBuilder.stub + this@MessageSubscribersBuilder.executeAndReply(this) { replier.invoke(this, find) } } @@ -888,8 +882,7 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R open infix fun String.startsWithReply(replier: @MessageDsl suspend M.(String) -> Any?): Ret { val toCheck = this.trimStart() return content({ it.trim().startsWith(toCheck) }, { - @Suppress("DSL_SCOPE_VIOLATION_WARNING") - this.executeAndReply { + this@MessageSubscribersBuilder.executeAndReply(this) { replier(this, it.trim().removePrefix(toCheck)) } }) @@ -912,8 +905,7 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R open infix fun String.endsWithReply(replier: @MessageDsl suspend M.(String) -> Any?): Ret { val toCheck = this.trimEnd() return content({ it.trim().endsWith(toCheck) }, { - @Suppress("DSL_SCOPE_VIOLATION_WARNING") - this.executeAndReply { + this@MessageSubscribersBuilder.executeAndReply(this) { replier(this, it.trim().removeSuffix(toCheck)) } }) @@ -922,13 +914,13 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R @MessageDsl open infix fun String.reply(reply: String): Ret { val toCheck = this.trim() - return content({ it.trim() == toCheck }, { reply(reply);stub }) + return content({ it.trim() == toCheck }, { reply(reply);this@MessageSubscribersBuilder.stub }) } @MessageDsl open infix fun String.reply(reply: Message): Ret { val toCheck = this.trim() - return content({ it.trim() == toCheck }, { reply(reply);stub }) + return content({ it.trim() == toCheck }, { reply(reply);this@MessageSubscribersBuilder.stub }) } @MessageDsl @@ -936,7 +928,7 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R val toCheck = this.trim() return content({ it.trim() == toCheck }, { @Suppress("DSL_SCOPE_VIOLATION_WARNING") - this.executeAndReply { + this@MessageSubscribersBuilder.executeAndReply(this) { replier(this, it.trim()) } }) @@ -944,26 +936,26 @@ open class MessageSubscribersBuilder, out Ret, R : RR, R @PublishedApi @Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE", "UNCHECKED_CAST") // false positive - internal suspend inline fun M.executeAndReply(replier: suspend M.(String) -> Any?): RR { - when (val message = replier(this, this.message.toString())) { - is Message -> this.reply(message) + internal suspend inline fun executeAndReply(m: M, replier: suspend M.(String) -> Any?): RR { + when (val message = replier(m, m.message.toString())) { + is Message -> m.reply(message) is Unit -> { } - else -> this.reply(message.toString()) + else -> m.reply(message.toString()) } return stub } @PublishedApi @Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE", "UNCHECKED_CAST") // false positive - internal suspend inline fun M.executeAndQuoteReply(replier: suspend M.(String) -> Any?): RR { - when (val message = replier(this, this.message.toString())) { - is Message -> this.quoteReply(message) + internal suspend inline fun executeAndQuoteReply(m: M, replier: suspend M.(String) -> Any?): RR { + when (val message = replier(m, m.message.toString())) { + is Message -> m.quoteReply(message) is Unit -> { } - else -> this.quoteReply(message.toString()) + else -> m.quoteReply(message.toString()) } return stub } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/contentToString.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/contentToString.kt index 6aa1922e5..0b1c651e7 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/contentToString.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/contentToString.kt @@ -13,7 +13,9 @@ package net.mamoe.mirai.utils import net.mamoe.mirai.utils.io.toUHexString import kotlin.reflect.KClass +import kotlin.reflect.KProperty import kotlin.reflect.KProperty1 +import kotlin.reflect.KType private val indent: String = " ".repeat(4) @@ -127,8 +129,14 @@ fun Any?._miraiContentToString(prefix: String = ""): String = when (this) { internal expect fun KProperty1<*, *>.getValueAgainstPermission(receiver: Any): Any? +private val KProperty1<*, *>.isConst: Boolean get() = false // on JVM, it will be resolved to member function +private val KClass<*>.isData: Boolean get() = false // on JVM, it will be resolved to member function + @MiraiDebugAPI -private fun Any.contentToStringReflectively(prefix: String, filter: ((name: String, value: Any?) -> Boolean)? = null): String { +private fun Any.contentToStringReflectively( + prefix: String, + filter: ((name: String, value: Any?) -> Boolean)? = null +): String { val newPrefix = "$prefix " return (this::class.simpleName ?: "") + "#" + this::class.hashCode() + " {\n" + this.allMembersFromSuperClassesMatching { it.qualifiedName?.startsWith("net.mamoe.mirai") == true } @@ -155,11 +163,14 @@ private fun Any.contentToStringReflectively(prefix: String, filter: ((name: Stri } + "\n$prefix}" } +private val KClass.supertypes: List get() = listOf() // on JVM, it will be resolved to member function + private fun KClass.thisClassAndSuperclassSequence(): Sequence> { return sequenceOf(this) + this.supertypes.asSequence() .mapNotNull { type -> type.classifier?.takeIf { it is KClass<*> }?.takeIf { it != Any::class } as? KClass }.flatMap { it.thisClassAndSuperclassSequence() } } +private val KClass.members: List> get() = listOf() // on JVM, it will be resolved to member function @Suppress("UNCHECKED_CAST") private fun Any.allMembersFromSuperClassesMatching(classFilter: (KClass) -> Boolean): Sequence> {