Merge branch 'master' into command

# Conflicts:
#	backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/permission/PermissionId.kt
This commit is contained in:
Him188 2020-10-24 21:22:46 +08:00
commit f80c4b3fd1
13 changed files with 71 additions and 36 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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"
}

View File

@ -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()
)

View File

@ -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)
}
}

View File

@ -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)

View File

@ -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() {

View File

@ -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

View File

@ -57,6 +57,8 @@ enum class ResolveContextKind {
PLUGIN_NAME,
PLUGIN_VERSION,
VERSION_REQUIREMENT,
COMMAND_NAME,
PERMISSION_NAMESPACE,

View File

@ -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"))
}

View File

@ -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() {

View File

@ -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(

View File

@ -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) {