diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/CombinedMessage.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/CombinedMessage.kt index f632f790b..73c4fa2c8 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/CombinedMessage.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/CombinedMessage.kt @@ -58,4 +58,8 @@ class CombinedMessage( override fun toString(): String { return element.toString() + left.toString() } + + fun isFlat(): Boolean { + return element is SingleMessage && left is SingleMessage + } } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt index 48eecf939..c59e942ac 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt @@ -61,7 +61,7 @@ interface MessageChain : Message, Iterable { fun getOrNull(key: Message.Key): M? = firstOrNull(key) /** - * 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage]. + * 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage], [QuoteReply]. * 仅供 `Java` 使用 */ @Suppress("FunctionName", "INAPPLICABLE_JVM_NAME") @@ -71,13 +71,26 @@ interface MessageChain : Message, Iterable { fun `__forEachContent for Java__`(block: (Message) -> Unit) { this.foreachContent(block) } + + /** + * 遍历每一个消息, 即 [MessageSource] [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage], [QuoteReply]. + * 仅供 `Java` 使用 + */ + @Suppress("FunctionName", "INAPPLICABLE_JVM_NAME") + @JsName("forEach") + @JvmName("forEach") + @MiraiInternalAPI + fun `__forEach for Java__`(block: (Message) -> Unit) { + this.forEach(block) + } } // region accessors /** - * 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage] + * 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage], [QuoteReply] */ +@JvmSynthetic inline fun MessageChain.foreachContent(block: (Message) -> Unit) { this.forEach { if (it !is MessageMetadata) block(it) @@ -87,23 +100,27 @@ inline fun MessageChain.foreachContent(block: (Message) -> Unit) { /** * 获取第一个 [M] 类型的 [Message] 实例 */ +@JvmSynthetic inline fun MessageChain.firstOrNull(): M? = this.firstOrNull { it is M } as M? /** * 获取第一个 [M] 类型的 [Message] 实例 * @throws [NoSuchElementException] 如果找不到该类型的实例 */ +@JvmSynthetic inline fun MessageChain.first(): M = this.first { it is M } as M /** * 获取第一个 [M] 类型的 [Message] 实例 */ +@JvmSynthetic inline fun MessageChain.any(): Boolean = this.any { it is M } /** * 获取第一个 [M] 类型的 [Message] 实例 */ +@JvmSynthetic @Suppress("UNCHECKED_CAST") fun MessageChain.firstOrNull(key: Message.Key): M? = when (key) { At -> first() @@ -120,6 +137,7 @@ fun MessageChain.firstOrNull(key: Message.Key): M? = when (key) * 获取第一个 [M] 类型的 [Message] 实例 * @throws [NoSuchElementException] 如果找不到该类型的实例 */ +@JvmSynthetic @Suppress("UNCHECKED_CAST") fun MessageChain.first(key: Message.Key): M = firstOrNull(key) ?: throw NoSuchElementException("no such element: $key") @@ -127,6 +145,7 @@ fun MessageChain.first(key: Message.Key): M = /** * 获取第一个 [M] 类型的 [Message] 实例 */ +@JvmSynthetic @Suppress("UNCHECKED_CAST") fun MessageChain.any(key: Message.Key): Boolean = firstOrNull(key) != null @@ -211,9 +230,6 @@ fun Message.asMessageChain(): MessageChain = when (this) { else -> SingleMessageChainImpl(this as SingleMessage) } -@Deprecated("use asMessageChain instead", ReplaceWith("this.asMessageChain()"), DeprecationLevel.ERROR) -fun Message.toChain(): MessageChain = this.asMessageChain() - /** * 直接将 [this] 委托为一个 [MessageChain] */ @@ -233,8 +249,18 @@ fun Collection.asMessageChain(): MessageChain = MessageChainImplBySeque @JvmSynthetic fun Iterable.asMessageChain(): MessageChain = MessageChainImplByIterable(this) +@JvmSynthetic inline fun MessageChain.asMessageChain(): MessageChain = this // 避免套娃 +@JvmSynthetic +fun CombinedMessage.asMessageChain(): MessageChain { + if (left is SingleMessage && this.element is SingleMessage) { + @Suppress("UNCHECKED_CAST") + return (this as Iterable).asMessageChain() + } + return (this as Iterable).asMessageChain() +} // 避免套娃 + /** * 将 [this] [扁平化后][flatten] 委托为一个 [MessageChain] */ @@ -324,11 +350,20 @@ fun Sequence.flatten(): Sequence = this // fast pa fun Message.flatten(): Sequence { return when (this) { is MessageChain -> this.asSequence() - is CombinedMessage -> this.asSequence().flatten() + is CombinedMessage -> this.flatten() else -> sequenceOf(this as SingleMessage) } } +fun CombinedMessage.flatten(): Sequence { + if (this.isFlat()){ + @Suppress("UNCHECKED_CAST") + return (this as Iterable).asSequence() + } else return this.asSequence().flatten() +} + +fun MessageChain.flatten(): Sequence = this.asSequence() // fast path + // endregion converters // region implementations