Introduce MessageScope

This commit is contained in:
Him188 2020-08-30 19:07:45 +08:00
parent ae4d5074a5
commit 6debc1d45b
5 changed files with 805 additions and 3 deletions

View File

@ -12,6 +12,25 @@
package net.mamoe.mirai.console.codegen
import org.intellij.lang.annotations.Language
import kotlin.reflect.KClass
import kotlin.reflect.full.functions
import kotlin.reflect.full.hasAnnotation
import kotlin.reflect.full.isSubclassOf
inline fun <reified T> runCodegenInObject() = runCodegenInObject(T::class)
fun runCodegenInObject(clazz: KClass<*>) {
clazz.nestedClasses
.filter { it.isSubclassOf(RegionCodegen::class) }
.associateWith { kClass -> kClass.functions.find { it.name == "main" && it.hasAnnotation<JvmStatic>() } }
.filter { it.value != null }
.forEach { (kClass, entryPoint) ->
println("---------------------------------------------")
println("Running Codegen: ${kClass.simpleName}")
entryPoint!!.call(kClass.objectInstance, arrayOf<String>())
println("---------------------------------------------")
}
}
abstract class Replacer(private val name: String) : (String) -> String {
override fun toString(): String {

View File

@ -0,0 +1,198 @@
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console.codegen
internal val TypeCandidatesForMessageScope = arrayOf(
KtType("Contact"),
KtType("CommandSender"),
)
internal val KtMessageScope = KtType("MessageScope")
internal fun <A> Array<A>.arrangements(): List<Pair<A, A>> {
val result = mutableListOf<Pair<A, A>>()
for (a in this) {
for (b in this) {
result.add(a to b)
}
}
return result
}
internal fun <A> Array<A>.distinctArrangements(): List<Pair<A, A>> {
return this.arrangements().distinctBy { it.first.toString().hashCode() + it.second.toString().hashCode() }
}
internal object MessageScopeCodegen {
object IterableMessageScopeBuildersCodegen : RegionCodegen("MessageScope.kt"), DefaultInvoke {
@JvmStatic
fun main(args: Array<String>) = super.startIndependently()
override val defaultInvokeArgs: List<KtType> = listOf(KtString) // invoke once
@Suppress(
"RedundantVisibilityModifier", "ClassName", "KDocUnresolvedReference", "RedundantSuspendModifier",
"SpellCheckingInspection"
)
override fun StringBuilder.apply(ktType: KtType) {
for (collectionName in arrayOf("Iterable", "Sequence", "Array")) {
for (candidate in (TypeCandidatesForMessageScope + KtMessageScope)) {
appendKCode(
"""
@JvmName("toMessageScope${candidate.standardName.capitalize()}${collectionName.capitalize()}")
public fun $collectionName<$candidate?>.toMessageScope(): MessageScope {
return this.fold(this.firstOrNull().asMessageScopeOrNoop()) { acc, messageScope -> CombinedScope(acc, messageScope.asMessageScopeOrNoop()) }
}
"""
)
appendLine()
}
}
for (candidate in (TypeCandidatesForMessageScope + KtMessageScope)) {
appendKCode(
"""
@JvmSynthetic
@JvmName("toMessageScope${candidate.standardName.capitalize()}Flow")
public suspend fun Flow<$candidate>.toMessageScope(): MessageScope { // Flow<Any?>.firstOrNull isn't yet supported
return this.fold(this.firstOrNull().asMessageScopeOrNoop()) { acc, messageScope -> CombinedScope(acc, messageScope.asMessageScope()) }
}
"""
)
appendLine()
}
}
}
object MessageScopeBuildersCodegen : RegionCodegen("MessageScope.kt"), DefaultInvoke {
@JvmStatic
fun main(args: Array<String>) = super.startIndependently()
override val defaultInvokeArgs: List<KtType> = listOf(KtString) // invoke once
@Suppress("RedundantVisibilityModifier", "ClassName", "KDocUnresolvedReference")
override fun StringBuilder.apply(ktType: KtType) {
for (candidate in TypeCandidatesForMessageScope) {
appendKCode(
"""
public fun ${candidate}.asMessageScope(): MessageScope = createScopeDelegate(this)
"""
)
appendLine()
}
for ((a, b) in (TypeCandidatesForMessageScope + KtMessageScope).arrangements()) {
appendKCode(
"""
@LowPriorityInOverloadResolution
public fun ${a}.scopeWith(vararg others: ${b}): MessageScope {
return others.fold(this.asMessageScope()) { acc, other -> CombinedScope(acc, other.asMessageScope()) }
}
"""
)
appendLine()
}
for ((a, b) in (TypeCandidatesForMessageScope + KtMessageScope).arrangements()) {
appendKCode(
"""
@LowPriorityInOverloadResolution
public fun ${a}?.scopeWithNotNull(vararg others: ${b}?): MessageScope {
return others.fold(this.asMessageScopeOrNoop()) { acc, other -> acc.scopeWithNotNull(other?.asMessageScope()) }
}
"""
)
appendLine()
}
for ((a, b) in (TypeCandidatesForMessageScope + KtMessageScope).distinctArrangements()) {
appendKCode(
"""
public fun ${a}.scopeWith(other: ${b}): MessageScope {
return CombinedScope(asMessageScope(), other.asMessageScope())
}
"""
)
appendLine()
}
for ((a, b) in (TypeCandidatesForMessageScope + KtMessageScope).distinctArrangements()) {
appendKCode(
"""
public fun ${a}?.scopeWithNotNull(other: ${b}?): MessageScope {
@Suppress("DuplicatedCode")
return when {
this == null && other == null -> NoopMessageScope
this == null && other != null -> other.asMessageScope()
this != null && other == null -> this.asMessageScope()
this != null && other != null -> CombinedScope(asMessageScope(), other.asMessageScope())
else -> null!!
}
}
"""
)
appendLine()
}
for ((a, b) in (TypeCandidatesForMessageScope + KtMessageScope).arrangements()) {
appendKCode(
"""
public inline fun <R> ${a}.scopeWith(vararg others: ${b}, action: MessageScope.() -> R): R {
return scopeWith(*others).invoke(action)
}
"""
)
appendLine()
}
for ((a, b) in (TypeCandidatesForMessageScope + KtMessageScope).arrangements()) {
appendKCode(
"""
public inline fun <R> ${a}?.scopeWithNotNull(vararg others: ${b}?, action: MessageScope.() -> R): R {
return scopeWithNotNull(*others).invoke(action)
}
"""
)
appendLine()
}
for (a in (TypeCandidatesForMessageScope + KtMessageScope)) {
appendKCode(
"""
@Deprecated("Senseless scopeWith. Use asMessageScope.", ReplaceWith("this.asMessageScope()", "net.mamoe.mirai.console.util.asMessageScope"))
public inline fun ${a}.scopeWith(): MessageScope = asMessageScope()
"""
)
appendLine()
}
for (a in (TypeCandidatesForMessageScope + KtMessageScope)) {
appendKCode(
"""
@Deprecated(
"Senseless scopeWith. Use .asMessageScope().invoke.",
ReplaceWith("this.asMessageScope()(action)", "net.mamoe.mirai.console.util.asMessageScope", "net.mamoe.mirai.console.util.invoke")
)
public inline fun <R> ${a}.scopeWith(action: MessageScope.() -> R): R = asMessageScope()(action)
"""
)
appendLine()
}
}
}
/**
* 运行本 object 中所有嵌套 object Codegen
*/
@OptIn(ExperimentalStdlibApi::class)
@JvmStatic
fun main(args: Array<String>) {
runCodegenInObject(this::class)
}
}

View File

@ -7,7 +7,7 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("NOTHING_TO_INLINE", "MemberVisibilityCanBePrivate", "unused","PRE_RELEASE_CLASS")
@file:Suppress("NOTHING_TO_INLINE", "MemberVisibilityCanBePrivate", "unused", "PRE_RELEASE_CLASS")
package net.mamoe.mirai.console.codegen
@ -71,6 +71,16 @@ sealed class KtType {
object KtMap : KtType() {
override val standardName: String get() = "Map"
}
data class Custom(override val standardName: String) : KtType() {
override fun toString(): String {
return standardName
}
}
companion object {
operator fun invoke(standardName: String): KtType = Custom(standardName)
}
}
val KtPrimitiveIntegers = listOf(KtByte, KtShort, KtInt, KtLong)

View File

@ -165,6 +165,7 @@ public interface CommandSender : CoroutineScope {
*
* 对于 [MemberCommandSender], 这个函数总是发送给所在群
*/
@JvmDefault
@JvmBlockingBridge
public suspend fun sendMessage(message: String): MessageReceipt<User>?
@ -259,9 +260,7 @@ public sealed class AbstractCommandSender : CommandSender, CoroutineScope {
public abstract override val bot: Bot?
public abstract override val subject: Contact?
public abstract override val user: User?
public abstract override suspend fun sendMessage(message: Message): MessageReceipt<User>?
public abstract override fun toString(): String
public override suspend fun sendMessage(message: String): MessageReceipt<User>? = sendMessage(PlainText(message))
@ConsoleExperimentalAPI("This is unstable and might get changed")
override suspend fun catchExecutionException(e: Throwable) {
@ -502,6 +501,11 @@ public abstract class ConsoleCommandSender @ConsoleFrontEndImplementation constr
MiraiConsoleImplementationBridge.consoleCommandSender.sendMessage(message)
return null
}
override suspend fun sendMessage(message: String): MessageReceipt<User>? {
MiraiConsoleImplementationBridge.consoleCommandSender.sendMessage(message)
return null
}
}
}
@ -567,7 +571,11 @@ public interface UserCommandSender : CommandSender {
public sealed class AbstractUserCommandSender : UserCommandSender, AbstractCommandSender() {
public override val bot: Bot get() = user.bot // don't final
public final override val name: String get() = user.nameCardOrNick
@JvmBlockingBridge
public override suspend fun sendMessage(message: String): MessageReceipt<User> = sendMessage(PlainText(message))
@JvmBlockingBridge
public override suspend fun sendMessage(message: Message): MessageReceipt<User> = user.sendMessage(message)
}
@ -580,7 +588,11 @@ public open class FriendCommandSender internal constructor(
) : AbstractUserCommandSender(), CoroutineScope by user.childScope("FriendCommandSender") {
public override val subject: Contact get() = user
public override fun toString(): String = "FriendCommandSender($user)"
@JvmBlockingBridge
public override suspend fun sendMessage(message: String): MessageReceipt<Friend> = sendMessage(PlainText(message))
@JvmBlockingBridge
public override suspend fun sendMessage(message: Message): MessageReceipt<Friend> = user.sendMessage(message)
}
@ -596,7 +608,11 @@ public open class MemberCommandSender internal constructor(
public override val group: Group get() = user.group
public override val subject: Contact get() = group
public override fun toString(): String = "MemberCommandSender($user)"
@JvmBlockingBridge
public override suspend fun sendMessage(message: String): MessageReceipt<Member> = sendMessage(PlainText(message))
@JvmBlockingBridge
public override suspend fun sendMessage(message: Message): MessageReceipt<Member> = user.sendMessage(message)
}
@ -612,7 +628,11 @@ public open class TempCommandSender internal constructor(
public override val group: Group get() = user.group
public override val subject: Contact get() = group
public override fun toString(): String = "TempCommandSender($user)"
@JvmBlockingBridge
public override suspend fun sendMessage(message: String): MessageReceipt<Member> = sendMessage(PlainText(message))
@JvmBlockingBridge
public override suspend fun sendMessage(message: Message): MessageReceipt<Member> = user.sendMessage(message)
}

View File

@ -0,0 +1,555 @@
/*
* Copyright 2019-2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress(
"NOTHING_TO_INLINE", "INAPPLICABLE_JVM_NAME", "FunctionName", "SuspendFunctionOnCoroutineScope",
"unused", "INVISIBLE_REFERENCE", "INVISIBLE_MEMBER"
)
package net.mamoe.mirai.console.util
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.fold
import net.mamoe.kjbb.JvmBlockingBridge
import net.mamoe.mirai.console.command.CommandSender
import net.mamoe.mirai.contact.Contact
import net.mamoe.mirai.message.data.Message
import kotlin.internal.InlineOnly
import kotlin.internal.LowPriorityInOverloadResolution
@ConsoleExperimentalAPI
public interface MessageScope {
/**
* 立刻发送一条消息.
*/
@JvmBlockingBridge
public suspend fun sendMessage(message: Message)
/**
* 立刻发送一条消息.
*/
@JvmDefault
@JvmBlockingBridge
public suspend fun sendMessage(message: String)
}
@JvmSynthetic
public inline operator fun <R, MS : MessageScope> MS.invoke(action: MS.() -> R): R = this.action()
///////////////////////////////////////////////////////////////////////////
// Builders
///////////////////////////////////////////////////////////////////////////
//// region MessageScopeBuilders CODEGEN ////
public fun Contact.asMessageScope(): MessageScope = createScopeDelegate(this)
public fun CommandSender.asMessageScope(): MessageScope = createScopeDelegate(this)
@LowPriorityInOverloadResolution
public fun Contact.scopeWith(vararg others: Contact): MessageScope {
return others.fold(this.asMessageScope()) { acc, other -> CombinedScope(acc, other.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun Contact.scopeWith(vararg others: CommandSender): MessageScope {
return others.fold(this.asMessageScope()) { acc, other -> CombinedScope(acc, other.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun Contact.scopeWith(vararg others: MessageScope): MessageScope {
return others.fold(this.asMessageScope()) { acc, other -> CombinedScope(acc, other.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun CommandSender.scopeWith(vararg others: Contact): MessageScope {
return others.fold(this.asMessageScope()) { acc, other -> CombinedScope(acc, other.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun CommandSender.scopeWith(vararg others: CommandSender): MessageScope {
return others.fold(this.asMessageScope()) { acc, other -> CombinedScope(acc, other.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun CommandSender.scopeWith(vararg others: MessageScope): MessageScope {
return others.fold(this.asMessageScope()) { acc, other -> CombinedScope(acc, other.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun MessageScope.scopeWith(vararg others: Contact): MessageScope {
return others.fold(this.asMessageScope()) { acc, other -> CombinedScope(acc, other.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun MessageScope.scopeWith(vararg others: CommandSender): MessageScope {
return others.fold(this.asMessageScope()) { acc, other -> CombinedScope(acc, other.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun MessageScope.scopeWith(vararg others: MessageScope): MessageScope {
return others.fold(this.asMessageScope()) { acc, other -> CombinedScope(acc, other.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun Contact?.scopeWithNotNull(vararg others: Contact?): MessageScope {
return others.fold(this.asMessageScopeOrNoop()) { acc, other -> acc.scopeWithNotNull(other?.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun Contact?.scopeWithNotNull(vararg others: CommandSender?): MessageScope {
return others.fold(this.asMessageScopeOrNoop()) { acc, other -> acc.scopeWithNotNull(other?.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun Contact?.scopeWithNotNull(vararg others: MessageScope?): MessageScope {
return others.fold(this.asMessageScopeOrNoop()) { acc, other -> acc.scopeWithNotNull(other?.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun CommandSender?.scopeWithNotNull(vararg others: Contact?): MessageScope {
return others.fold(this.asMessageScopeOrNoop()) { acc, other -> acc.scopeWithNotNull(other?.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun CommandSender?.scopeWithNotNull(vararg others: CommandSender?): MessageScope {
return others.fold(this.asMessageScopeOrNoop()) { acc, other -> acc.scopeWithNotNull(other?.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun CommandSender?.scopeWithNotNull(vararg others: MessageScope?): MessageScope {
return others.fold(this.asMessageScopeOrNoop()) { acc, other -> acc.scopeWithNotNull(other?.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun MessageScope?.scopeWithNotNull(vararg others: Contact?): MessageScope {
return others.fold(this.asMessageScopeOrNoop()) { acc, other -> acc.scopeWithNotNull(other?.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun MessageScope?.scopeWithNotNull(vararg others: CommandSender?): MessageScope {
return others.fold(this.asMessageScopeOrNoop()) { acc, other -> acc.scopeWithNotNull(other?.asMessageScope()) }
}
@LowPriorityInOverloadResolution
public fun MessageScope?.scopeWithNotNull(vararg others: MessageScope?): MessageScope {
return others.fold(this.asMessageScopeOrNoop()) { acc, other -> acc.scopeWithNotNull(other?.asMessageScope()) }
}
public fun Contact.scopeWith(other: Contact): MessageScope {
return CombinedScope(asMessageScope(), other.asMessageScope())
}
public fun Contact.scopeWith(other: CommandSender): MessageScope {
return CombinedScope(asMessageScope(), other.asMessageScope())
}
public fun Contact.scopeWith(other: MessageScope): MessageScope {
return CombinedScope(asMessageScope(), other.asMessageScope())
}
public fun CommandSender.scopeWith(other: CommandSender): MessageScope {
return CombinedScope(asMessageScope(), other.asMessageScope())
}
public fun CommandSender.scopeWith(other: MessageScope): MessageScope {
return CombinedScope(asMessageScope(), other.asMessageScope())
}
public fun MessageScope.scopeWith(other: MessageScope): MessageScope {
return CombinedScope(asMessageScope(), other.asMessageScope())
}
public fun Contact?.scopeWithNotNull(other: Contact?): MessageScope {
@Suppress("DuplicatedCode")
return when {
this == null && other == null -> NoopMessageScope
this == null && other != null -> other.asMessageScope()
this != null && other == null -> this.asMessageScope()
this != null && other != null -> CombinedScope(asMessageScope(), other.asMessageScope())
else -> null!!
}
}
public fun Contact?.scopeWithNotNull(other: CommandSender?): MessageScope {
@Suppress("DuplicatedCode")
return when {
this == null && other == null -> NoopMessageScope
this == null && other != null -> other.asMessageScope()
this != null && other == null -> this.asMessageScope()
this != null && other != null -> CombinedScope(asMessageScope(), other.asMessageScope())
else -> null!!
}
}
public fun Contact?.scopeWithNotNull(other: MessageScope?): MessageScope {
@Suppress("DuplicatedCode")
return when {
this == null && other == null -> NoopMessageScope
this == null && other != null -> other.asMessageScope()
this != null && other == null -> this.asMessageScope()
this != null && other != null -> CombinedScope(asMessageScope(), other.asMessageScope())
else -> null!!
}
}
public fun CommandSender?.scopeWithNotNull(other: CommandSender?): MessageScope {
@Suppress("DuplicatedCode")
return when {
this == null && other == null -> NoopMessageScope
this == null && other != null -> other.asMessageScope()
this != null && other == null -> this.asMessageScope()
this != null && other != null -> CombinedScope(asMessageScope(), other.asMessageScope())
else -> null!!
}
}
public fun CommandSender?.scopeWithNotNull(other: MessageScope?): MessageScope {
@Suppress("DuplicatedCode")
return when {
this == null && other == null -> NoopMessageScope
this == null && other != null -> other.asMessageScope()
this != null && other == null -> this.asMessageScope()
this != null && other != null -> CombinedScope(asMessageScope(), other.asMessageScope())
else -> null!!
}
}
public fun MessageScope?.scopeWithNotNull(other: MessageScope?): MessageScope {
@Suppress("DuplicatedCode")
return when {
this == null && other == null -> NoopMessageScope
this == null && other != null -> other.asMessageScope()
this != null && other == null -> this.asMessageScope()
this != null && other != null -> CombinedScope(asMessageScope(), other.asMessageScope())
else -> null!!
}
}
public inline fun <R> Contact.scopeWith(vararg others: Contact, action: MessageScope.() -> R): R {
return scopeWith(*others).invoke(action)
}
public inline fun <R> Contact.scopeWith(vararg others: CommandSender, action: MessageScope.() -> R): R {
return scopeWith(*others).invoke(action)
}
public inline fun <R> Contact.scopeWith(vararg others: MessageScope, action: MessageScope.() -> R): R {
return scopeWith(*others).invoke(action)
}
public inline fun <R> CommandSender.scopeWith(vararg others: Contact, action: MessageScope.() -> R): R {
return scopeWith(*others).invoke(action)
}
public inline fun <R> CommandSender.scopeWith(vararg others: CommandSender, action: MessageScope.() -> R): R {
return scopeWith(*others).invoke(action)
}
public inline fun <R> CommandSender.scopeWith(vararg others: MessageScope, action: MessageScope.() -> R): R {
return scopeWith(*others).invoke(action)
}
public inline fun <R> MessageScope.scopeWith(vararg others: Contact, action: MessageScope.() -> R): R {
return scopeWith(*others).invoke(action)
}
public inline fun <R> MessageScope.scopeWith(vararg others: CommandSender, action: MessageScope.() -> R): R {
return scopeWith(*others).invoke(action)
}
public inline fun <R> MessageScope.scopeWith(vararg others: MessageScope, action: MessageScope.() -> R): R {
return scopeWith(*others).invoke(action)
}
public inline fun <R> Contact?.scopeWithNotNull(vararg others: Contact?, action: MessageScope.() -> R): R {
return scopeWithNotNull(*others).invoke(action)
}
public inline fun <R> Contact?.scopeWithNotNull(vararg others: CommandSender?, action: MessageScope.() -> R): R {
return scopeWithNotNull(*others).invoke(action)
}
public inline fun <R> Contact?.scopeWithNotNull(vararg others: MessageScope?, action: MessageScope.() -> R): R {
return scopeWithNotNull(*others).invoke(action)
}
public inline fun <R> CommandSender?.scopeWithNotNull(vararg others: Contact?, action: MessageScope.() -> R): R {
return scopeWithNotNull(*others).invoke(action)
}
public inline fun <R> CommandSender?.scopeWithNotNull(vararg others: CommandSender?, action: MessageScope.() -> R): R {
return scopeWithNotNull(*others).invoke(action)
}
public inline fun <R> CommandSender?.scopeWithNotNull(vararg others: MessageScope?, action: MessageScope.() -> R): R {
return scopeWithNotNull(*others).invoke(action)
}
public inline fun <R> MessageScope?.scopeWithNotNull(vararg others: Contact?, action: MessageScope.() -> R): R {
return scopeWithNotNull(*others).invoke(action)
}
public inline fun <R> MessageScope?.scopeWithNotNull(vararg others: CommandSender?, action: MessageScope.() -> R): R {
return scopeWithNotNull(*others).invoke(action)
}
public inline fun <R> MessageScope?.scopeWithNotNull(vararg others: MessageScope?, action: MessageScope.() -> R): R {
return scopeWithNotNull(*others).invoke(action)
}
@Deprecated(
"Senseless scopeWith. Use asMessageScope.",
ReplaceWith("this.asMessageScope()", "net.mamoe.mirai.console.util.asMessageScope")
)
public inline fun Contact.scopeWith(): MessageScope = asMessageScope()
@Deprecated(
"Senseless scopeWith. Use asMessageScope.",
ReplaceWith("this.asMessageScope()", "net.mamoe.mirai.console.util.asMessageScope")
)
public inline fun CommandSender.scopeWith(): MessageScope = asMessageScope()
@Deprecated(
"Senseless scopeWith. Use asMessageScope.",
ReplaceWith("this.asMessageScope()", "net.mamoe.mirai.console.util.asMessageScope")
)
public inline fun MessageScope.scopeWith(): MessageScope = asMessageScope()
@Deprecated(
"Senseless scopeWith. Use .asMessageScope().invoke.",
ReplaceWith(
"this.asMessageScope()(action)",
"net.mamoe.mirai.console.util.asMessageScope",
"net.mamoe.mirai.console.util.invoke"
)
)
public inline fun <R> Contact.scopeWith(action: MessageScope.() -> R): R = asMessageScope()(action)
@Deprecated(
"Senseless scopeWith. Use .asMessageScope().invoke.",
ReplaceWith(
"this.asMessageScope()(action)",
"net.mamoe.mirai.console.util.asMessageScope",
"net.mamoe.mirai.console.util.invoke"
)
)
public inline fun <R> CommandSender.scopeWith(action: MessageScope.() -> R): R = asMessageScope()(action)
@Deprecated(
"Senseless scopeWith. Use .asMessageScope().invoke.",
ReplaceWith(
"this.asMessageScope()(action)",
"net.mamoe.mirai.console.util.asMessageScope",
"net.mamoe.mirai.console.util.invoke"
)
)
public inline fun <R> MessageScope.scopeWith(action: MessageScope.() -> R): R = asMessageScope()(action)
//// endregion MessageScopeBuilders CODEGEN ////
//// region IterableMessageScopeBuilders CODEGEN ////
@JvmName("toMessageScopeContactIterable")
public fun Iterable<Contact?>.toMessageScope(): MessageScope {
return this.fold(this.firstOrNull().asMessageScopeOrNoop()) { acc, messageScope ->
CombinedScope(
acc,
messageScope.asMessageScopeOrNoop()
)
}
}
@JvmName("toMessageScopeCommandSenderIterable")
public fun Iterable<CommandSender?>.toMessageScope(): MessageScope {
return this.fold(this.firstOrNull().asMessageScopeOrNoop()) { acc, messageScope ->
CombinedScope(
acc,
messageScope.asMessageScopeOrNoop()
)
}
}
@JvmName("toMessageScopeMessageScopeIterable")
public fun Iterable<MessageScope?>.toMessageScope(): MessageScope {
return this.fold(this.firstOrNull().asMessageScopeOrNoop()) { acc, messageScope ->
CombinedScope(
acc,
messageScope.asMessageScopeOrNoop()
)
}
}
@JvmName("toMessageScopeContactSequence")
public fun Sequence<Contact?>.toMessageScope(): MessageScope {
return this.fold(this.firstOrNull().asMessageScopeOrNoop()) { acc, messageScope ->
CombinedScope(
acc,
messageScope.asMessageScopeOrNoop()
)
}
}
@JvmName("toMessageScopeCommandSenderSequence")
public fun Sequence<CommandSender?>.toMessageScope(): MessageScope {
return this.fold(this.firstOrNull().asMessageScopeOrNoop()) { acc, messageScope ->
CombinedScope(
acc,
messageScope.asMessageScopeOrNoop()
)
}
}
@JvmName("toMessageScopeMessageScopeSequence")
public fun Sequence<MessageScope?>.toMessageScope(): MessageScope {
return this.fold(this.firstOrNull().asMessageScopeOrNoop()) { acc, messageScope ->
CombinedScope(
acc,
messageScope.asMessageScopeOrNoop()
)
}
}
@JvmName("toMessageScopeContactArray")
public fun Array<Contact?>.toMessageScope(): MessageScope {
return this.fold(this.firstOrNull().asMessageScopeOrNoop()) { acc, messageScope ->
CombinedScope(
acc,
messageScope.asMessageScopeOrNoop()
)
}
}
@JvmName("toMessageScopeCommandSenderArray")
public fun Array<CommandSender?>.toMessageScope(): MessageScope {
return this.fold(this.firstOrNull().asMessageScopeOrNoop()) { acc, messageScope ->
CombinedScope(
acc,
messageScope.asMessageScopeOrNoop()
)
}
}
@JvmName("toMessageScopeMessageScopeArray")
public fun Array<MessageScope?>.toMessageScope(): MessageScope {
return this.fold(this.firstOrNull().asMessageScopeOrNoop()) { acc, messageScope ->
CombinedScope(
acc,
messageScope.asMessageScopeOrNoop()
)
}
}
@JvmSynthetic
@JvmName("toMessageScopeContactFlow")
public suspend fun Flow<Contact>.toMessageScope(): MessageScope { // Flow<Any?>.firstOrNull isn't yet supported
return this.fold(this.firstOrNull().asMessageScopeOrNoop()) { acc, messageScope ->
CombinedScope(
acc,
messageScope.asMessageScope()
)
}
}
@JvmSynthetic
@JvmName("toMessageScopeCommandSenderFlow")
public suspend fun Flow<CommandSender>.toMessageScope(): MessageScope { // Flow<Any?>.firstOrNull isn't yet supported
return this.fold(this.firstOrNull().asMessageScopeOrNoop()) { acc, messageScope ->
CombinedScope(
acc,
messageScope.asMessageScope()
)
}
}
@JvmSynthetic
@JvmName("toMessageScopeMessageScopeFlow")
public suspend fun Flow<MessageScope>.toMessageScope(): MessageScope { // Flow<Any?>.firstOrNull isn't yet supported
return this.fold(this.firstOrNull().asMessageScopeOrNoop()) { acc, messageScope ->
CombinedScope(
acc,
messageScope.asMessageScope()
)
}
}
//// endregion IterableMessageScopeBuilders CODEGEN ////
///////////////////////////////////////////////////////////////////////////
// Internals
///////////////////////////////////////////////////////////////////////////
// these three are for codegen
@PublishedApi
@InlineOnly
internal inline fun MessageScope.asMessageScope(): MessageScope = this
@InlineOnly
private inline fun MessageScope?.asMessageScopeOrNoop(): MessageScope = this?.asMessageScope() ?: NoopMessageScope
@InlineOnly
private inline fun Contact?.asMessageScopeOrNoop(): MessageScope = this?.asMessageScope() ?: NoopMessageScope
@InlineOnly
private inline fun CommandSender?.asMessageScopeOrNoop(): MessageScope = this?.asMessageScope() ?: NoopMessageScope
@InlineOnly
private inline fun createScopeDelegate(o: CommandSender) = CommandSenderAsMessageScope(o)
@InlineOnly
private inline fun createScopeDelegate(o: Contact) = ContactAsMessageScope(o)
private class CombinedScope(
private val first: MessageScope,
private val second: MessageScope
) : MessageScope {
override suspend fun sendMessage(message: Message) {
first.sendMessage(message)
second.sendMessage(message)
}
override suspend fun sendMessage(message: String) {
first.sendMessage(message)
second.sendMessage(message)
}
}
private class CommandSenderAsMessageScope(
private val sender: CommandSender
) : MessageScope {
override suspend fun sendMessage(message: Message) {
sender.sendMessage(message)
}
override suspend fun sendMessage(message: String) {
sender.sendMessage(message)
}
}
private class ContactAsMessageScope(
private val sender: Contact
) : MessageScope {
override suspend fun sendMessage(message: Message) {
sender.sendMessage(message)
}
override suspend fun sendMessage(message: String) {
sender.sendMessage(message)
}
}
private object NoopMessageScope : MessageScope {
override suspend fun sendMessage(message: Message) {
}
override suspend fun sendMessage(message: String) {
}
}