mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-10 18:40:15 +08:00
Merge remote-tracking branch 'console/master'
This commit is contained in:
commit
a2e7112cd3
@ -17,9 +17,13 @@ import net.mamoe.mirai.Bot
|
|||||||
import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start
|
import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start
|
||||||
import net.mamoe.mirai.console.command.ConsoleCommandSender
|
import net.mamoe.mirai.console.command.ConsoleCommandSender
|
||||||
import net.mamoe.mirai.console.data.PluginDataStorage
|
import net.mamoe.mirai.console.data.PluginDataStorage
|
||||||
|
import net.mamoe.mirai.console.extension.ComponentStorage
|
||||||
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
||||||
|
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
||||||
import net.mamoe.mirai.console.internal.logging.LoggerControllerImpl
|
import net.mamoe.mirai.console.internal.logging.LoggerControllerImpl
|
||||||
|
import net.mamoe.mirai.console.internal.plugin.PluginManagerImpl
|
||||||
import net.mamoe.mirai.console.logging.LoggerController
|
import net.mamoe.mirai.console.logging.LoggerController
|
||||||
|
import net.mamoe.mirai.console.plugin.Plugin
|
||||||
import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader
|
import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader
|
||||||
import net.mamoe.mirai.console.plugin.loader.PluginLoader
|
import net.mamoe.mirai.console.plugin.loader.PluginLoader
|
||||||
import net.mamoe.mirai.console.util.ConsoleInput
|
import net.mamoe.mirai.console.util.ConsoleInput
|
||||||
@ -185,8 +189,72 @@ public interface MiraiConsoleImplementation : CoroutineScope {
|
|||||||
public val loggerController: LoggerController get() = LoggerControllerImpl
|
public val loggerController: LoggerController get() = LoggerControllerImpl
|
||||||
|
|
||||||
|
|
||||||
|
/// Hooks & Backend Access
|
||||||
|
/**
|
||||||
|
* 后端 在 [phase] 阶段执行前会调用此方法, 如果此方法抛出了一个错误会直接中断 console 初始化
|
||||||
|
*
|
||||||
|
* @since 2.5.0-dev-2
|
||||||
|
*/
|
||||||
|
public fun prePhase(phase: String) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后端 在 [phase] 阶段执行后会调用此方法, 如果此方法抛出了一个错误会直接中断 console 初始化
|
||||||
|
*
|
||||||
|
* @since 2.5.0-dev-2
|
||||||
|
*/
|
||||||
|
public fun postPhase(phase: String) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后端在 [start] 前会调用此方法
|
||||||
|
*
|
||||||
|
* @since 2.5.0-dev-2
|
||||||
|
*/
|
||||||
|
public fun preStart() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后端在 [start] 后会调用此方法
|
||||||
|
*
|
||||||
|
* @since 2.5.0-dev-2
|
||||||
|
*/
|
||||||
|
public fun postStart() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前端访问后端内部实现的桥
|
||||||
|
*
|
||||||
|
* @see backendAccess
|
||||||
|
* @since 2.5.0-dev-2
|
||||||
|
*/
|
||||||
|
@ConsoleFrontEndImplementation
|
||||||
|
public interface BackendAccess {
|
||||||
|
// GlobalComponentStorage
|
||||||
|
public val globalComponentStorage: ComponentStorage
|
||||||
|
|
||||||
|
// PluginManagerImpl.resolvedPlugins
|
||||||
|
public val resolvedPlugins: MutableList<Plugin>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BackendAccess
|
||||||
|
* @since 2.5.0-dev-2
|
||||||
|
* @throws IllegalStateException 当前端实例不是 `this` 时抛出
|
||||||
|
*/
|
||||||
|
public val backendAccess: BackendAccess
|
||||||
|
get() {
|
||||||
|
if (instanceInitialized) {
|
||||||
|
if (this === instance)
|
||||||
|
return backendAccessInstance
|
||||||
|
}
|
||||||
|
throw IllegalStateException("Permission denied")
|
||||||
|
}
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
|
private val backendAccessInstance = object : BackendAccess {
|
||||||
|
override val globalComponentStorage: ComponentStorage get() = GlobalComponentStorage
|
||||||
|
override val resolvedPlugins: MutableList<Plugin> get() = PluginManagerImpl.resolvedPlugins
|
||||||
|
}
|
||||||
|
|
||||||
internal lateinit var instance: MiraiConsoleImplementation
|
internal lateinit var instance: MiraiConsoleImplementation
|
||||||
|
internal val instanceInitialized: Boolean get() = ::instance.isInitialized
|
||||||
private val initLock = ReentrantLock()
|
private val initLock = ReentrantLock()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,6 +37,7 @@ import net.mamoe.mirai.console.permission.PermissionService
|
|||||||
import net.mamoe.mirai.console.permission.PermissionService.Companion.cancel
|
import net.mamoe.mirai.console.permission.PermissionService.Companion.cancel
|
||||||
import net.mamoe.mirai.console.permission.PermissionService.Companion.findCorrespondingPermissionOrFail
|
import net.mamoe.mirai.console.permission.PermissionService.Companion.findCorrespondingPermissionOrFail
|
||||||
import net.mamoe.mirai.console.permission.PermissionService.Companion.getPermittedPermissions
|
import net.mamoe.mirai.console.permission.PermissionService.Companion.getPermittedPermissions
|
||||||
|
import net.mamoe.mirai.console.permission.PermissionService.Companion.hasPermission
|
||||||
import net.mamoe.mirai.console.permission.PermissionService.Companion.permit
|
import net.mamoe.mirai.console.permission.PermissionService.Companion.permit
|
||||||
import net.mamoe.mirai.console.permission.PermitteeId
|
import net.mamoe.mirai.console.permission.PermitteeId
|
||||||
import net.mamoe.mirai.console.plugin.name
|
import net.mamoe.mirai.console.plugin.name
|
||||||
@ -98,6 +99,7 @@ public object BuiltInCommands {
|
|||||||
public suspend fun CommandSender.handle() {
|
public suspend fun CommandSender.handle() {
|
||||||
sendMessage(
|
sendMessage(
|
||||||
allRegisteredCommands
|
allRegisteredCommands
|
||||||
|
.filter { hasPermission(it.permission) }
|
||||||
.joinToString("\n\n") { command ->
|
.joinToString("\n\n") { command ->
|
||||||
val lines = command.usage.lines()
|
val lines = command.usage.lines()
|
||||||
if (lines.isEmpty()) "/${command.primaryName} ${command.description}"
|
if (lines.isEmpty()) "/${command.primaryName} ${command.description}"
|
||||||
|
@ -121,7 +121,7 @@ public abstract class CompositeCommand(
|
|||||||
@Retention(RUNTIME)
|
@Retention(RUNTIME)
|
||||||
@Target(FUNCTION)
|
@Target(FUNCTION)
|
||||||
protected annotation class SubCommand(
|
protected annotation class SubCommand(
|
||||||
@ResolveContext(COMMAND_NAME) vararg val value: String,
|
@ResolveContext(COMMAND_NAME) vararg val value: String = [],
|
||||||
)
|
)
|
||||||
|
|
||||||
/** 指令描述 */
|
/** 指令描述 */
|
||||||
|
@ -14,8 +14,8 @@ import java.time.Instant
|
|||||||
|
|
||||||
internal object MiraiConsoleBuildConstants { // auto-filled on build (task :mirai-console:fillBuildConstants)
|
internal object MiraiConsoleBuildConstants { // auto-filled on build (task :mirai-console:fillBuildConstants)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
val buildDate: Instant = Instant.ofEpochSecond(1613042196)
|
val buildDate: Instant = Instant.ofEpochSecond(1613308312)
|
||||||
const val versionConst: String = "2.4-RC"
|
const val versionConst: String = "2.4.0"
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
val version: SemVersion = SemVersion(versionConst)
|
val version: SemVersion = SemVersion(versionConst)
|
||||||
|
@ -16,7 +16,10 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import net.mamoe.mirai.Bot
|
import net.mamoe.mirai.Bot
|
||||||
import net.mamoe.mirai.console.*
|
import net.mamoe.mirai.console.MalformedMiraiConsoleImplementationError
|
||||||
|
import net.mamoe.mirai.console.MiraiConsole
|
||||||
|
import net.mamoe.mirai.console.MiraiConsoleFrontEndDescription
|
||||||
|
import net.mamoe.mirai.console.MiraiConsoleImplementation
|
||||||
import net.mamoe.mirai.console.command.BuiltInCommands
|
import net.mamoe.mirai.console.command.BuiltInCommands
|
||||||
import net.mamoe.mirai.console.command.CommandManager
|
import net.mamoe.mirai.console.command.CommandManager
|
||||||
import net.mamoe.mirai.console.command.ConsoleCommandSender
|
import net.mamoe.mirai.console.command.ConsoleCommandSender
|
||||||
@ -104,8 +107,9 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
|
|||||||
|
|
||||||
@Suppress("RemoveRedundantBackticks")
|
@Suppress("RemoveRedundantBackticks")
|
||||||
internal fun doStart() {
|
internal fun doStart() {
|
||||||
|
instance.preStart()
|
||||||
|
|
||||||
phase `setup logger controller`@{
|
phase("setup logger controller") {
|
||||||
if (loggerController === LoggerControllerImpl) {
|
if (loggerController === LoggerControllerImpl) {
|
||||||
// Reload LoggerConfig.
|
// Reload LoggerConfig.
|
||||||
ConsoleDataScope.addAndReloadConfig(LoggerConfig)
|
ConsoleDataScope.addAndReloadConfig(LoggerConfig)
|
||||||
@ -113,7 +117,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
phase `greeting`@{
|
phase("greeting") {
|
||||||
val buildDateFormatted =
|
val buildDateFormatted =
|
||||||
buildDate.atZone(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
|
buildDate.atZone(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
|
||||||
|
|
||||||
@ -122,7 +126,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
|
|||||||
mainLogger.info { frontEndDescription.render() }
|
mainLogger.info { frontEndDescription.render() }
|
||||||
}
|
}
|
||||||
|
|
||||||
phase `check coroutineContext`@{
|
phase("check coroutineContext") {
|
||||||
if (coroutineContext[Job] == null) {
|
if (coroutineContext[Job] == null) {
|
||||||
throw MalformedMiraiConsoleImplementationError("The coroutineContext given to MiraiConsole must have a Job in it.")
|
throw MalformedMiraiConsoleImplementationError("The coroutineContext given to MiraiConsole must have a Job in it.")
|
||||||
}
|
}
|
||||||
@ -139,13 +143,13 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
|
|||||||
|
|
||||||
// start
|
// start
|
||||||
|
|
||||||
phase `load configurations`@{
|
phase("load configurations") {
|
||||||
mainLogger.verbose { "Loading configurations..." }
|
mainLogger.verbose { "Loading configurations..." }
|
||||||
ConsoleDataScope.addAndReloadConfig(CommandConfig)
|
ConsoleDataScope.addAndReloadConfig(CommandConfig)
|
||||||
ConsoleDataScope.reloadAll()
|
ConsoleDataScope.reloadAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
phase `initialize all plugins`@{
|
phase("initialize all plugins") {
|
||||||
PluginManager // init
|
PluginManager // init
|
||||||
|
|
||||||
mainLogger.verbose { "Loading JVM plugins..." }
|
mainLogger.verbose { "Loading JVM plugins..." }
|
||||||
@ -158,13 +162,13 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
phase `load all plugins`@{
|
phase("load all plugins") {
|
||||||
PluginManagerImpl.loadPlugins(PluginManagerImpl.scanPluginsUsingPluginLoadersIncludingThoseFromPluginLoaderProvider())
|
PluginManagerImpl.loadPlugins(PluginManagerImpl.scanPluginsUsingPluginLoadersIncludingThoseFromPluginLoaderProvider())
|
||||||
|
|
||||||
mainLogger.verbose { "${PluginManager.plugins.size} plugin(s) loaded." }
|
mainLogger.verbose { "${PluginManager.plugins.size} plugin(s) loaded." }
|
||||||
}
|
}
|
||||||
|
|
||||||
phase `load SingletonExtensionSelector`@{
|
phase("load SingletonExtensionSelector") {
|
||||||
SingletonExtensionSelector.init()
|
SingletonExtensionSelector.init()
|
||||||
val instance = SingletonExtensionSelector.instance
|
val instance = SingletonExtensionSelector.instance
|
||||||
if (instance is BuiltInSingletonExtensionSelector) {
|
if (instance is BuiltInSingletonExtensionSelector) {
|
||||||
@ -173,7 +177,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
phase `load PermissionService`@{
|
phase("load PermissionService") {
|
||||||
mainLogger.verbose { "Loading PermissionService..." }
|
mainLogger.verbose { "Loading PermissionService..." }
|
||||||
|
|
||||||
PermissionService.INSTANCE.let { ps ->
|
PermissionService.INSTANCE.let { ps ->
|
||||||
@ -188,7 +192,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
|
|||||||
runIgnoreException<UnsupportedOperationException> { ConsoleCommandSender.permit(RootPermission) }
|
runIgnoreException<UnsupportedOperationException> { ConsoleCommandSender.permit(RootPermission) }
|
||||||
}
|
}
|
||||||
|
|
||||||
phase `prepare commands`@{
|
phase("prepare commands") {
|
||||||
mainLogger.verbose { "Loading built-in commands..." }
|
mainLogger.verbose { "Loading built-in commands..." }
|
||||||
BuiltInCommands.registerAll()
|
BuiltInCommands.registerAll()
|
||||||
mainLogger.info { "Prepared built-in commands: ${BuiltInCommands.all.joinToString { it.primaryName }}" }
|
mainLogger.info { "Prepared built-in commands: ${BuiltInCommands.all.joinToString { it.primaryName }}" }
|
||||||
@ -196,7 +200,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
|
|||||||
// CommandManagerImpl.commandListener // start
|
// CommandManagerImpl.commandListener // start
|
||||||
}
|
}
|
||||||
|
|
||||||
phase `enable plugins`@{
|
phase("enable plugins") {
|
||||||
mainLogger.verbose { "Enabling plugins..." }
|
mainLogger.verbose { "Enabling plugins..." }
|
||||||
|
|
||||||
PluginManagerImpl.enableAllLoadedPlugins()
|
PluginManagerImpl.enableAllLoadedPlugins()
|
||||||
@ -208,7 +212,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
|
|||||||
mainLogger.info { "${PluginManagerImpl.plugins.size} plugin(s) enabled." }
|
mainLogger.info { "${PluginManagerImpl.plugins.size} plugin(s) enabled." }
|
||||||
}
|
}
|
||||||
|
|
||||||
phase `auto-login bots`@{
|
phase("auto-login bots") {
|
||||||
runBlocking {
|
runBlocking {
|
||||||
val accounts = AutoLoginConfig.accounts.toList()
|
val accounts = AutoLoginConfig.accounts.toList()
|
||||||
for (account in accounts) {
|
for (account in accounts) {
|
||||||
@ -259,10 +263,14 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalComponentStorage.run {
|
phase("finally post") {
|
||||||
PostStartupExtension.useExtensions { it() } // exceptions thrown will be caught by caller of `doStart`.
|
GlobalComponentStorage.run {
|
||||||
|
PostStartupExtension.useExtensions { it() } // exceptions thrown will be caught by caller of `doStart`.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
instance.postStart()
|
||||||
|
|
||||||
mainLogger.info { "mirai-console started successfully." }
|
mainLogger.info { "mirai-console started successfully." }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,10 +283,20 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
|
|||||||
* 表示一个初始化阶段, 无实际作用.
|
* 表示一个初始化阶段, 无实际作用.
|
||||||
*/
|
*/
|
||||||
@ILoveOmaeKumikoForever
|
@ILoveOmaeKumikoForever
|
||||||
private inline fun phase(block: () -> Unit) {
|
private inline fun phase(phase: String, block: () -> Unit) {
|
||||||
contract {
|
contract {
|
||||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
}
|
}
|
||||||
|
prePhase(phase)
|
||||||
block()
|
block()
|
||||||
|
postPhase(phase)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun prePhase(phase: String) {
|
||||||
|
instance.prePhase(phase)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun postPhase(phase: String) {
|
||||||
|
instance.postPhase(phase)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -203,10 +203,12 @@ internal class CommandReflector(
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun CommandParameter<*>.toErasedParameterInfo(index: Int): ErasedParameterInfo {
|
fun CommandParameter<*>.toErasedParameterInfo(index: Int): ErasedParameterInfo {
|
||||||
return ErasedParameterInfo(index,
|
return ErasedParameterInfo(
|
||||||
|
index,
|
||||||
this.name,
|
this.name,
|
||||||
this.type.withNullability(false),
|
this.type.withNullability(false),
|
||||||
if (this is AbstractCommandValueParameter.StringConstant) this.expectingValue else null)
|
if (this is AbstractCommandValueParameter.StringConstant) this.expectingValue else null
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val candidates = signatures.map { variant ->
|
val candidates = signatures.map { variant ->
|
||||||
@ -244,11 +246,21 @@ internal class CommandReflector(
|
|||||||
name?.split(' ')?.mapIndexed { index, s -> createStringConstantParameterForName(index, s) }
|
name?.split(' ')?.mapIndexed { index, s -> createStringConstantParameterForName(index, s) }
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
|
|
||||||
|
val valueParameters = function.valueParameters.toMutableList()
|
||||||
|
var receiverParameter = function.extensionReceiverParameter
|
||||||
|
if (receiverParameter == null && valueParameters.isNotEmpty()) {
|
||||||
|
val valueFirstParameter = valueParameters[0]
|
||||||
|
if (valueFirstParameter.type.classifierAsKClassOrNull()?.isSubclassOf(CommandSender::class) == true) {
|
||||||
|
receiverParameter = valueFirstParameter
|
||||||
|
valueParameters.removeAt(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val functionValueParameters =
|
val functionValueParameters =
|
||||||
function.valueParameters.associateBy { it.toUserDefinedCommandParameter() }
|
valueParameters.associateBy { it.toUserDefinedCommandParameter() }
|
||||||
|
|
||||||
CommandSignatureFromKFunctionImpl(
|
CommandSignatureFromKFunctionImpl(
|
||||||
receiverParameter = function.extensionReceiverParameter?.toCommandReceiverParameter(),
|
receiverParameter = receiverParameter?.toCommandReceiverParameter(),
|
||||||
valueParameters = functionNameAsValueParameter + functionValueParameters.keys,
|
valueParameters = functionNameAsValueParameter + functionValueParameters.keys,
|
||||||
originFunction = function
|
originFunction = function
|
||||||
) { call ->
|
) { call ->
|
||||||
@ -272,7 +284,6 @@ internal class CommandReflector(
|
|||||||
args[instanceParameter] = command
|
args[instanceParameter] = command
|
||||||
}
|
}
|
||||||
|
|
||||||
val receiverParameter = function.extensionReceiverParameter
|
|
||||||
if (receiverParameter != null) {
|
if (receiverParameter != null) {
|
||||||
check(receiverParameter.type.classifierAsKClass().isInstance(call.caller)) {
|
check(receiverParameter.type.classifierAsKClass().isInstance(call.caller)) {
|
||||||
"Bad command call resolved. " +
|
"Bad command call resolved. " +
|
||||||
|
@ -14,7 +14,6 @@ package net.mamoe.mirai.console.internal.util
|
|||||||
import net.mamoe.mirai.console.internal.data.cast
|
import net.mamoe.mirai.console.internal.data.cast
|
||||||
import net.mamoe.mirai.console.internal.data.createInstanceOrNull
|
import net.mamoe.mirai.console.internal.data.createInstanceOrNull
|
||||||
import net.mamoe.mirai.console.internal.plugin.BuiltInJvmPluginLoaderImpl
|
import net.mamoe.mirai.console.internal.plugin.BuiltInJvmPluginLoaderImpl
|
||||||
import java.io.InputStream
|
|
||||||
import java.lang.reflect.Modifier
|
import java.lang.reflect.Modifier
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
@ -30,9 +29,13 @@ internal object PluginServiceHelper {
|
|||||||
|
|
||||||
fun <T : Any> ClassLoader.findServices(vararg serviceTypes: KClass<out T>): ServiceList<T> =
|
fun <T : Any> ClassLoader.findServices(vararg serviceTypes: KClass<out T>): ServiceList<T> =
|
||||||
serviceTypes.flatMap { serviceType ->
|
serviceTypes.flatMap { serviceType ->
|
||||||
getResourceAsStream("META-INF/services/" + serviceType.qualifiedName!!)
|
getResourceAsStream("META-INF/services/" + serviceType.qualifiedName!!)?.let { stream ->
|
||||||
?.use(InputStream::readBytes)
|
stream.bufferedReader().useLines { lines ->
|
||||||
?.let(::String)?.lines()?.filter(String::isNotBlank).orEmpty()
|
lines.filter(String::isNotBlank)
|
||||||
|
.filter { it[0] != '#' }
|
||||||
|
.toList()
|
||||||
|
}
|
||||||
|
}.orEmpty()
|
||||||
}.let { ServiceList(this, it) }
|
}.let { ServiceList(this, it) }
|
||||||
|
|
||||||
fun <T : Any> ServiceList<T>.loadAllServices(): List<T> {
|
fun <T : Any> ServiceList<T>.loadAllServices(): List<T> {
|
||||||
|
@ -69,9 +69,11 @@ object TestEnumArgCommand : CompositeCommand(owner, "testenum") {
|
|||||||
enum class TestEnum {
|
enum class TestEnum {
|
||||||
V1, V2, V3
|
V1, V2, V3
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class TestCase {
|
enum class TestCase {
|
||||||
A, a
|
A, a
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class TestCamelCase {
|
enum class TestCamelCase {
|
||||||
A, B, A_B
|
A, B, A_B
|
||||||
}
|
}
|
||||||
@ -295,6 +297,36 @@ internal class TestCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test first param command sender`() = runBlocking<Unit> {
|
||||||
|
object : CompositeCommand(owner, "cmd") {
|
||||||
|
@SubCommand
|
||||||
|
fun handle(sender: CommandSender, arg: String) {
|
||||||
|
Testing.ok(arg)
|
||||||
|
}
|
||||||
|
}.withRegistration {
|
||||||
|
assertEquals("test", withTesting { assertSuccess(execute(sender, "handle test")) })
|
||||||
|
}
|
||||||
|
|
||||||
|
object : SimpleCommand(owner, "cmd") {
|
||||||
|
@Handler
|
||||||
|
fun handle(sender: CommandSender, arg: String) {
|
||||||
|
Testing.ok(arg)
|
||||||
|
}
|
||||||
|
}.withRegistration {
|
||||||
|
assertEquals("hello", withTesting { assertSuccess(execute(sender, "hello")) })
|
||||||
|
}
|
||||||
|
|
||||||
|
object : SimpleCommand(owner, "cmd") {
|
||||||
|
@Handler
|
||||||
|
fun handle(arg: String, sender: CommandSender) {
|
||||||
|
Testing.ok(arg)
|
||||||
|
}
|
||||||
|
}.withRegistration {
|
||||||
|
assertFailure(execute(sender, "hello"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `composite sub command resolution conflict`() {
|
fun `composite sub command resolution conflict`() {
|
||||||
runBlocking {
|
runBlocking {
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2021 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
|
||||||
|
*/
|
||||||
|
|
||||||
@file:Suppress("UnstableApiUsage")
|
@file:Suppress("UnstableApiUsage")
|
||||||
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.*
|
import org.jetbrains.kotlin.gradle.dsl.*
|
||||||
@ -26,7 +35,6 @@ allprojects {
|
|||||||
maven(url = "https://dl.bintray.com/kotlin/kotlin-eap")
|
maven(url = "https://dl.bintray.com/kotlin/kotlin-eap")
|
||||||
jcenter()
|
jcenter()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven(url = "https://dl.bintray.com/karlatemp/misc")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ const val yamlkt = "net.mamoe.yamlkt:yamlkt:${Versions.yamlkt}"
|
|||||||
const val `jetbrains-annotations` = "org.jetbrains:annotations:19.0.0"
|
const val `jetbrains-annotations` = "org.jetbrains:annotations:19.0.0"
|
||||||
|
|
||||||
|
|
||||||
const val `caller-finder` = "io.github.karlatemp:caller:1.0.1"
|
const val `caller-finder` = "io.github.karlatemp:caller:1.1.1"
|
||||||
|
|
||||||
|
|
||||||
val ATTRIBUTE_MIRAI_TARGET_PLATFORM: Attribute<String> = Attribute.of("mirai.target.platform", String::class.java)
|
val ATTRIBUTE_MIRAI_TARGET_PLATFORM: Attribute<String> = Attribute.of("mirai.target.platform", String::class.java)
|
@ -10,6 +10,6 @@
|
|||||||
package net.mamoe.mirai.console.gradle
|
package net.mamoe.mirai.console.gradle
|
||||||
|
|
||||||
internal object VersionConstants {
|
internal object VersionConstants {
|
||||||
const val CONSOLE_VERSION = "2.4-RC" // value is written here automatically during build
|
const val CONSOLE_VERSION = "2.4.0" // value is written here automatically during build
|
||||||
const val CORE_VERSION = "2.4-RC" // value is written here automatically during build
|
const val CORE_VERSION = "2.4.0" // value is written here automatically during build
|
||||||
}
|
}
|
@ -11,7 +11,19 @@ import java.io.IOException;
|
|||||||
import static org.example.myplugin.ResourceNotClosedInspectionTestKt.magic;
|
import static org.example.myplugin.ResourceNotClosedInspectionTestKt.magic;
|
||||||
|
|
||||||
public class ResourceNotClosedInspectionTestJava {
|
public class ResourceNotClosedInspectionTestJava {
|
||||||
|
|
||||||
|
public static Object funA() {
|
||||||
|
return new Object();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void funB(Object obj) {
|
||||||
|
System.out.println(obj);
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
// https://github.com/mamoe/mirai-console/issues/294
|
||||||
|
funB(funA());
|
||||||
|
|
||||||
File file = magic();
|
File file = magic();
|
||||||
Contact contact = magic();
|
Contact contact = magic();
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package test;
|
|||||||
import net.mamoe.mirai.console.command.Command;
|
import net.mamoe.mirai.console.command.Command;
|
||||||
import net.mamoe.mirai.console.command.CommandOwner;
|
import net.mamoe.mirai.console.command.CommandOwner;
|
||||||
import net.mamoe.mirai.console.command.descriptor.CommandSignatureFromKFunction;
|
import net.mamoe.mirai.console.command.descriptor.CommandSignatureFromKFunction;
|
||||||
|
import net.mamoe.mirai.console.command.java.JCompositeCommand;
|
||||||
import net.mamoe.mirai.console.command.java.JSimpleCommand;
|
import net.mamoe.mirai.console.command.java.JSimpleCommand;
|
||||||
import net.mamoe.mirai.console.permission.Permission;
|
import net.mamoe.mirai.console.permission.Permission;
|
||||||
import net.mamoe.mirai.console.plugin.jvm.JavaPlugin;
|
import net.mamoe.mirai.console.plugin.jvm.JavaPlugin;
|
||||||
@ -28,3 +29,16 @@ class TestCommand extends JSimpleCommand {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestCommand2 extends JCompositeCommand {
|
||||||
|
public TestCommand2(@NotNull CommandOwner owner, @NotNull String primaryName, @NotNull String[] secondaryNames, @NotNull Permission parentPermission) {
|
||||||
|
super(owner, primaryName, secondaryNames, parentPermission);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubCommand("test")
|
||||||
|
public void test() {}
|
||||||
|
|
||||||
|
@SubCommand({})
|
||||||
|
public void subCmd() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -96,16 +96,21 @@ fun KtFunction.hasSignature(functionSignature: FunctionSignature): Boolean {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun KtLightMethod.hasSignature(functionSignature: FunctionSignature): Boolean {
|
|
||||||
|
fun PsiMethod.hasSignature(functionSignature: FunctionSignature): Boolean {
|
||||||
if (functionSignature.name != null) {
|
if (functionSignature.name != null) {
|
||||||
if (this.name != functionSignature.name) return false
|
if (this.name != functionSignature.name) return false
|
||||||
}
|
}
|
||||||
val parameters = parameterList.parameters.toMutableList()
|
val parameters = parameterList.parameters.toMutableList()
|
||||||
if (functionSignature.dispatchReceiver != null) {
|
if (functionSignature.dispatchReceiver != null) {
|
||||||
val kotlinContainingClassFqn =
|
val containingClass = this.containingClass ?: return false
|
||||||
|
|
||||||
|
val kotlinContainingClassFqn = if (this is KtLightMethod) {
|
||||||
if (this.modifierList.hasExplicitModifier(PsiModifier.STATIC)) {
|
if (this.modifierList.hasExplicitModifier(PsiModifier.STATIC)) {
|
||||||
this.containingClass.kotlinOrigin?.companionObjects?.firstOrNull()?.fqName
|
this.containingClass.kotlinOrigin?.companionObjects?.firstOrNull()?.fqName
|
||||||
} else this.containingClass.getKotlinFqName()
|
} else containingClass.getKotlinFqName()
|
||||||
|
} else containingClass.getKotlinFqName()
|
||||||
|
|
||||||
if (kotlinContainingClassFqn != functionSignature.dispatchReceiver) return false
|
if (kotlinContainingClassFqn != functionSignature.dispatchReceiver) return false
|
||||||
}
|
}
|
||||||
if (functionSignature.extensionReceiver != null) {
|
if (functionSignature.extensionReceiver != null) {
|
||||||
@ -121,12 +126,6 @@ fun KtLightMethod.hasSignature(functionSignature: FunctionSignature): Boolean {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PsiMethod.hasSignature(functionSignature: FunctionSignature): Boolean {
|
|
||||||
if (this is KtLightMethod) {
|
|
||||||
return this.hasSignature(functionSignature)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
fun KtExpression.isCalling(functionSignature: FunctionSignature): Boolean {
|
fun KtExpression.isCalling(functionSignature: FunctionSignature): Boolean {
|
||||||
val descriptor = resolveToCall(BodyResolveMode.PARTIAL)?.resultingDescriptor ?: return false
|
val descriptor = resolveToCall(BodyResolveMode.PARTIAL)?.resultingDescriptor ?: return false
|
||||||
|
Loading…
Reference in New Issue
Block a user