mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-10 18:40:15 +08:00
Merge branch 'master' into command
# Conflicts: # backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/permission/PermissionId.kt
This commit is contained in:
commit
f80c4b3fd1
@ -40,6 +40,8 @@ public annotation class ResolveContext(
|
||||
PLUGIN_NAME, // ILLEGAL_PLUGIN_DESCRIPTION
|
||||
PLUGIN_VERSION, // ILLEGAL_PLUGIN_DESCRIPTION
|
||||
|
||||
VERSION_REQUIREMENT, // ILLEGAL_VERSION_REQUIREMENT // TODO
|
||||
|
||||
COMMAND_NAME, // ILLEGAL_COMMAND_NAME
|
||||
|
||||
PERMISSION_NAMESPACE, // ILLEGAL_COMMAND_NAMESPACE
|
||||
|
@ -182,7 +182,7 @@ internal inline fun AtomicLong.updateWhen(condition: (Long) -> Boolean, update:
|
||||
while (true) {
|
||||
val current = value
|
||||
if (condition(current)) {
|
||||
if (compareAndSet(0, update(current))) {
|
||||
if (compareAndSet(current, update(current))) {
|
||||
return true
|
||||
} else continue
|
||||
}
|
||||
|
@ -31,10 +31,10 @@ public data class PermissionId(
|
||||
@ResolveContext(PERMISSION_NAME) public val name: String,
|
||||
) {
|
||||
init {
|
||||
require(!namespace.contains(' ')) {
|
||||
require(namespace.none { it.isWhitespace() }) {
|
||||
"' ' is not allowed in namespace"
|
||||
}
|
||||
require(!name.contains(' ')) {
|
||||
require(name.none { it.isWhitespace() }) {
|
||||
"' ' is not allowed in name"
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ import net.mamoe.mirai.console.extensions.PermissionServiceProvider
|
||||
import net.mamoe.mirai.console.internal.permission.checkType
|
||||
import net.mamoe.mirai.console.permission.Permission.Companion.parentsWithSelf
|
||||
import net.mamoe.mirai.console.plugin.Plugin
|
||||
import net.mamoe.mirai.console.plugin.description
|
||||
import net.mamoe.mirai.console.plugin.name
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@ -154,7 +155,7 @@ public interface PermissionService<P : Permission> {
|
||||
@ResolveContext(COMMAND_NAME) permissionName: String,
|
||||
reason: PluginPermissionIdRequestType
|
||||
) = PermissionId(
|
||||
plugin.name.toLowerCase().replace(' ', '.'),
|
||||
plugin.description.id.toLowerCase(),
|
||||
permissionName.toLowerCase()
|
||||
)
|
||||
|
||||
|
@ -35,7 +35,7 @@ public interface JvmPluginDescription : PluginDescription {
|
||||
*/
|
||||
@JvmName("create")
|
||||
@JvmSynthetic
|
||||
public operator fun invoke(
|
||||
public inline operator fun invoke(
|
||||
/**
|
||||
* @see [PluginDescription.id]
|
||||
*/
|
||||
@ -57,7 +57,7 @@ public interface JvmPluginDescription : PluginDescription {
|
||||
*/
|
||||
@JvmName("create")
|
||||
@JvmSynthetic
|
||||
public operator fun invoke(
|
||||
public inline operator fun invoke(
|
||||
/**
|
||||
* @see [PluginDescription.id]
|
||||
*/
|
||||
@ -65,7 +65,7 @@ public interface JvmPluginDescription : PluginDescription {
|
||||
/**
|
||||
* @see [PluginDescription.version]
|
||||
*/
|
||||
@ResolveContext(PLUGIN_VERSION) version: SemVersion,
|
||||
version: SemVersion,
|
||||
/**
|
||||
* @see [PluginDescription.name]
|
||||
*/
|
||||
@ -87,17 +87,17 @@ public interface JvmPluginDescription : PluginDescription {
|
||||
* ```
|
||||
*
|
||||
* #### Java Example
|
||||
* ```
|
||||
* ```java
|
||||
* JvmPluginDescription desc = new JvmPluginDescriptionBuilder("org.example.example-plugin", "1.0.0")
|
||||
* .info("This is an example plugin")
|
||||
* .dependsOn("org.example.another-plugin")
|
||||
* .build()
|
||||
* .build();
|
||||
* ```
|
||||
*
|
||||
* @see [JvmPluginDescription.invoke]
|
||||
*/
|
||||
public class JvmPluginDescriptionBuilder(
|
||||
private var id: String,
|
||||
@ResolveContext(PLUGIN_ID) private var id: String,
|
||||
private var version: SemVersion,
|
||||
) {
|
||||
public constructor(
|
||||
@ -119,7 +119,7 @@ public class JvmPluginDescriptionBuilder(
|
||||
apply { this.version = SemVersion(value) }
|
||||
|
||||
@ILoveKuriyamaMiraiForever
|
||||
public fun version(@ResolveContext(PLUGIN_VERSION) value: SemVersion): JvmPluginDescriptionBuilder =
|
||||
public fun version(value: SemVersion): JvmPluginDescriptionBuilder =
|
||||
apply { this.version = value }
|
||||
|
||||
@ILoveKuriyamaMiraiForever
|
||||
@ -148,18 +148,6 @@ public class JvmPluginDescriptionBuilder(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PluginDependency
|
||||
*/
|
||||
@ILoveKuriyamaMiraiForever
|
||||
public fun dependsOn(
|
||||
@ResolveContext(PLUGIN_ID) pluginId: String,
|
||||
isOptional: Boolean = false,
|
||||
versionRequirement: SemVersion.Requirement,
|
||||
): JvmPluginDescriptionBuilder = apply {
|
||||
this.dependencies.add(PluginDependency(pluginId, versionRequirement, isOptional))
|
||||
}
|
||||
|
||||
/**
|
||||
* isOptional = false
|
||||
*
|
||||
@ -169,13 +157,28 @@ public class JvmPluginDescriptionBuilder(
|
||||
public fun dependsOn(
|
||||
@ResolveContext(PLUGIN_ID) pluginId: String,
|
||||
versionRequirement: SemVersion.Requirement,
|
||||
isOptional: Boolean = false,
|
||||
): JvmPluginDescriptionBuilder = apply {
|
||||
this.dependencies.add(PluginDependency(pluginId, versionRequirement, false))
|
||||
this.dependencies.add(PluginDependency(pluginId, versionRequirement, isOptional))
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PluginDependency
|
||||
*/
|
||||
@ILoveKuriyamaMiraiForever
|
||||
public fun dependsOn(
|
||||
@ResolveContext(PLUGIN_ID) pluginId: String,
|
||||
@ResolveContext(VERSION_REQUIREMENT) versionRequirement: String,
|
||||
isOptional: Boolean = false,
|
||||
): JvmPluginDescriptionBuilder = apply {
|
||||
this.dependencies.add(PluginDependency(pluginId, SemVersion.parseRangeRequirement(versionRequirement), isOptional))
|
||||
}
|
||||
|
||||
/**
|
||||
* 无版本要求
|
||||
*
|
||||
* @param isOptional [PluginDependency.isOptional]
|
||||
*
|
||||
* @see PluginDependency
|
||||
*/
|
||||
@ILoveKuriyamaMiraiForever
|
||||
@ -187,8 +190,8 @@ public class JvmPluginDescriptionBuilder(
|
||||
}
|
||||
|
||||
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
public fun build(): JvmPluginDescription =
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
SimpleJvmPluginDescription(name, version, id, author, info, dependencies)
|
||||
|
||||
/**
|
||||
@ -227,6 +230,6 @@ internal data class SimpleJvmPluginDescription
|
||||
) : this(name, SemVersion(version), id, author, info, dependencies)
|
||||
|
||||
init {
|
||||
require(!name.contains(':')) { "':' is forbidden in plugin name" }
|
||||
PluginDescription.checkPluginDescription(this)
|
||||
}
|
||||
}
|
@ -22,10 +22,12 @@ import kotlinx.serialization.Transient
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
import net.mamoe.mirai.console.compiler.common.ResolveContext
|
||||
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.PLUGIN_VERSION
|
||||
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.VERSION_REQUIREMENT
|
||||
import net.mamoe.mirai.console.internal.data.map
|
||||
import net.mamoe.mirai.console.internal.util.semver.SemVersionInternal
|
||||
import net.mamoe.mirai.console.util.SemVersion.Companion.equals
|
||||
import net.mamoe.mirai.console.util.SemVersion.Requirement
|
||||
import kotlin.LazyThreadSafetyMode.PUBLICATION
|
||||
|
||||
/**
|
||||
* [语义化版本](https://semver.org/lang/zh-CN/) 支持
|
||||
@ -138,7 +140,7 @@ internal constructor(
|
||||
*/
|
||||
@Throws(IllegalArgumentException::class)
|
||||
@JvmStatic
|
||||
public fun parseRangeRequirement(requirement: String): Requirement =
|
||||
public fun parseRangeRequirement(@ResolveContext(VERSION_REQUIREMENT) requirement: String): Requirement =
|
||||
SemVersionInternal.parseRangeRequirement(requirement)
|
||||
|
||||
/** @see [Requirement.test] */
|
||||
@ -151,6 +153,12 @@ internal constructor(
|
||||
@JvmStatic
|
||||
public fun SemVersion.satisfies(requirement: Requirement): Boolean = requirement.test(this)
|
||||
|
||||
/**
|
||||
* 当满足 [requirement] 时返回 true, 否则返回 false
|
||||
*/
|
||||
@JvmStatic
|
||||
public fun SemVersion.satisfies(@ResolveContext(VERSION_REQUIREMENT) requirement: String): Boolean = parseRangeRequirement(requirement).test(this)
|
||||
|
||||
/** for Kotlin only */
|
||||
@JvmStatic
|
||||
@JvmSynthetic
|
||||
@ -163,7 +171,7 @@ internal constructor(
|
||||
}
|
||||
|
||||
@Transient
|
||||
private val toString: String by lazy(LazyThreadSafetyMode.NONE) {
|
||||
private val toString: String by lazy(PUBLICATION) {
|
||||
buildString {
|
||||
append(major)
|
||||
append('.').append(minor)
|
||||
|
@ -1,8 +1,18 @@
|
||||
package net.mamoe.mirai.console.permission
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertFails
|
||||
|
||||
internal class PermissionsBasicsTest {
|
||||
@Test
|
||||
fun testInvalidPermissionId() {
|
||||
assertFails { PermissionId("space namespace", "name") }
|
||||
assertFails { PermissionId("namespace", "space name") }
|
||||
// assertFails { PermissionId("", "name") }
|
||||
// assertFails { PermissionId("namespace", "") }
|
||||
assertFails { PermissionId("namespace:name", "name") }
|
||||
assertFails { PermissionId("namespace", "namespace:name") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parentsWithSelfSequence() {
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
object Versions {
|
||||
const val core = "1.3.0"
|
||||
const val console = "1.0-RC-dev-30"
|
||||
const val console = "1.0-RC-dev-31"
|
||||
const val consoleGraphical = "0.0.7"
|
||||
const val consoleTerminal = console
|
||||
|
||||
|
@ -57,6 +57,8 @@ enum class ResolveContextKind {
|
||||
PLUGIN_NAME,
|
||||
PLUGIN_VERSION,
|
||||
|
||||
VERSION_REQUIREMENT,
|
||||
|
||||
COMMAND_NAME,
|
||||
|
||||
PERMISSION_NAMESPACE,
|
||||
|
@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
kotlin("jvm") version "1.4.0"
|
||||
kotlin("plugin.serialization") version "1.4.0"
|
||||
kotlin("kapt") version "1.4.0"
|
||||
kotlin("jvm") version "1.4.10"
|
||||
kotlin("plugin.serialization") version "1.4.10"
|
||||
kotlin("kapt") version "1.4.10"
|
||||
id("com.github.johnrengelman.shadow") version "5.2.0"
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ dependencies {
|
||||
|
||||
testImplementation("net.mamoe:mirai-console:$console")
|
||||
testImplementation("net.mamoe:mirai-core:$core")
|
||||
testImplementation("net.mamoe:mirai-console-pure:$console")
|
||||
testImplementation("net.mamoe:mirai-console-terminal:$console")
|
||||
testImplementation(kotlin("stdlib-jdk8"))
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,8 @@ object MyPluginMain : KotlinPlugin(
|
||||
override fun onEnable() {
|
||||
super.onEnable()
|
||||
PermissionService.INSTANCE.register(permissionId("dvs"), "ok")
|
||||
PermissionService.INSTANCE.register(permissionId("perm with space"), "error")
|
||||
PermissionId("Namespace with space", "Name with space")
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
@ -85,7 +85,7 @@ class ContextualParametersChecker : DeclarationChecker {
|
||||
fun checkPermissionNamespace(inspectionTarget: PsiElement, value: String): Diagnostic? {
|
||||
return when {
|
||||
value.isBlank() -> ILLEGAL_PERMISSION_NAMESPACE.on(inspectionTarget, value, "权限命名空间不能为空")
|
||||
value.any { it.isWhitespace() } -> ILLEGAL_PERMISSION_NAMESPACE.on(inspectionTarget, value, "暂时不允许权限命名空间中存在空格")
|
||||
value.any { it.isWhitespace() } -> ILLEGAL_PERMISSION_NAMESPACE.on(inspectionTarget, value, "不允许权限命名空间中存在空格")
|
||||
value.contains(':') -> ILLEGAL_PERMISSION_NAMESPACE.on(inspectionTarget, value, "权限命名空间不允许包含 ':'")
|
||||
else -> null
|
||||
}
|
||||
@ -94,7 +94,7 @@ class ContextualParametersChecker : DeclarationChecker {
|
||||
fun checkPermissionName(inspectionTarget: PsiElement, value: String): Diagnostic? {
|
||||
return when {
|
||||
value.isBlank() -> ILLEGAL_PERMISSION_NAME.on(inspectionTarget, value, "权限名称不能为空")
|
||||
value.any { it.isWhitespace() } -> ILLEGAL_PERMISSION_NAME.on(inspectionTarget, value, "暂时不允许权限名称中存在空格")
|
||||
value.any { it.isWhitespace() } -> ILLEGAL_PERMISSION_NAME.on(inspectionTarget, value, "不允许权限名称中存在空格")
|
||||
value.contains(':') -> ILLEGAL_PERMISSION_NAME.on(inspectionTarget, value, "权限名称不允许包含 ':'")
|
||||
else -> null
|
||||
}
|
||||
@ -108,6 +108,12 @@ class ContextualParametersChecker : DeclarationChecker {
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
fun checkVersionRequirement(inspectionTarget: PsiElement, value: String): Diagnostic? {
|
||||
// TODO: 2020/10/23 checkVersionRequirement
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private val checkersMap: EnumMap<ResolveContextKind, (declaration: PsiElement, value: String) -> Diagnostic?> =
|
||||
@ -119,6 +125,7 @@ class ContextualParametersChecker : DeclarationChecker {
|
||||
put(ResolveContextKind.PERMISSION_NAME, ::checkPermissionName)
|
||||
put(ResolveContextKind.PERMISSION_NAMESPACE, ::checkPermissionNamespace)
|
||||
put(ResolveContextKind.PERMISSION_ID, ::checkPermissionId)
|
||||
put(ResolveContextKind.VERSION_REQUIREMENT, ::checkVersionRequirement)
|
||||
}
|
||||
|
||||
override fun check(
|
||||
|
@ -25,7 +25,7 @@ class AddSerializerFix(
|
||||
element: KtClassOrObject,
|
||||
) : KotlinCrossLanguageQuickFixAction<KtModifierListOwner>(element), KotlinUniversalQuickFix {
|
||||
|
||||
override fun getFamilyName(): String = "添加注解"
|
||||
override fun getFamilyName(): String = "Mirai Console"
|
||||
override fun getText(): String = "添加 @Serializable"
|
||||
|
||||
override fun invokeImpl(project: Project, editor: Editor?, file: PsiFile) {
|
||||
|
Loading…
Reference in New Issue
Block a user