Migrate to Kotlin 1.4

This commit is contained in:
Him188 2020-03-24 13:42:33 +08:00
parent eb7afb6cff
commit 70dd71cb61
4 changed files with 56 additions and 70 deletions

View File

@ -115,24 +115,9 @@ internal class Handler<in E : Event>
*/
internal fun <E : Event> KClass<out E>.listeners(): EventListeners<E> = EventListenerManager.get(this)
internal class EventListeners<E : Event>(clazz: KClass<E>) : LockFreeLinkedList<Listener<E>>() {
internal expect class EventListeners<E : Event>(clazz: KClass<E>) : LockFreeLinkedList<Listener<E>> {
@Suppress("UNCHECKED_CAST", "UNSUPPORTED", "NO_REFLECTION_IN_CLASS_PATH")
val supertypes: Set<KClass<out Event>> by lazy {
val supertypes = mutableSetOf<KClass<out Event>>()
fun addSupertypes(clazz: KClass<out Event>) {
clazz.supertypes.forEach {
val classifier = it.classifier as? KClass<out Event>
if (classifier != null) {
supertypes.add(classifier)
addSupertypes(classifier)
}
}
}
addSupertypes(clazz)
supertypes
}
val supertypes: Set<KClass<out Event>>
}
internal expect class MiraiAtomicBoolean(initial: Boolean) {

View File

@ -285,7 +285,7 @@ abstract class MessageSelectBuilderUnit<M : MessagePacket<*, *>, R> @PublishedAp
* 在超时后引用回复原消息
*
* [block] 返回值为 [Unit] 时不回复, [Message] 时回复 [Message], 其他将 [toString] 后回复为 [PlainText]
*
* @see timeout
* @see reply
*/
@ -304,8 +304,7 @@ abstract class MessageSelectBuilderUnit<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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?) {

View File

@ -262,7 +262,6 @@ typealias MessageListener<T, R> = @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<M : MessagePacket<*, *>, out Ret, R : RR, RR>(
@ -318,37 +317,36 @@ open class MessageSubscribersBuilder<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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<M : MessagePacket<*, *>, 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
}

View File

@ -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 ?: "<UnnamedClass>") + "#" + 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 <T : Any> KClass<T>.supertypes: List<KType> get() = listOf() // on JVM, it will be resolved to member function
private fun KClass<out Any>.thisClassAndSuperclassSequence(): Sequence<KClass<out Any>> {
return sequenceOf(this) +
this.supertypes.asSequence()
.mapNotNull { type -> type.classifier?.takeIf { it is KClass<*> }?.takeIf { it != Any::class } as? KClass<out Any> }.flatMap { it.thisClassAndSuperclassSequence() }
}
private val <T : Any> KClass<T>.members: List<KProperty<*>> get() = listOf() // on JVM, it will be resolved to member function
@Suppress("UNCHECKED_CAST")
private fun Any.allMembersFromSuperClassesMatching(classFilter: (KClass<out Any>) -> Boolean): Sequence<KProperty1<Any, *>> {