From 6a2ef97b41a46a2c15ebc21146eddd6c089a74fc Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 18 Sep 2020 10:07:50 +0800 Subject: [PATCH] Improve description checker: support compile-time constants --- .../.images/ILLEGAL_PLUGIN_DESCRIPTION.png | Bin 0 -> 15581 bytes tools/intellij-plugin/README.md | 12 ++++- .../org/example/myplugin/MyPluginMain.kt | 18 +++++++- .../diagnostics/PluginDescriptionChecker.kt | 42 +++++++++--------- .../console/intellij/resolve/resolveIdea.kt | 21 ++++++++- 5 files changed, 68 insertions(+), 25 deletions(-) create mode 100644 tools/intellij-plugin/.images/ILLEGAL_PLUGIN_DESCRIPTION.png diff --git a/tools/intellij-plugin/.images/ILLEGAL_PLUGIN_DESCRIPTION.png b/tools/intellij-plugin/.images/ILLEGAL_PLUGIN_DESCRIPTION.png new file mode 100644 index 0000000000000000000000000000000000000000..830a907e4df699d88437723a70266df4ec9c698d GIT binary patch literal 15581 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 literal 0 HcmV?d00001 diff --git a/tools/intellij-plugin/README.md b/tools/intellij-plugin/README.md index da5b520e0..1d79320c2 100644 --- a/tools/intellij-plugin/README.md +++ b/tools/intellij-plugin/README.md @@ -4,4 +4,14 @@ IntelliJ 平台的 Mirai Console 开发插件 ## 功能 -### 诊断 \ No newline at end of file +### 诊断 + +#### ILLEGAL_PLUGIN_DESCRIPTION + +[PluginDescriptionChecker.kt](src/main/kotlin/net/mamoe/mirai/console/intellij/diagnostics/PluginDescriptionChecker.kt#L34) + +- 使用 [ResolveContext](../../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/compiler/common/ResolveContext.kt) +- 检测 Plugin Id, Plugin Name, Plugin Version 的合法性. 并在非法时提示正确的语法. +- 支持编译期常量 + +![ILLEGAL_PLUGIN_DESCRIPTION](.images/ILLEGAL_PLUGIN_DESCRIPTION.png) diff --git a/tools/intellij-plugin/run/projects/test-project/src/main/kotlin/org/example/myplugin/MyPluginMain.kt b/tools/intellij-plugin/run/projects/test-project/src/main/kotlin/org/example/myplugin/MyPluginMain.kt index 7abb6a55c..9f1bdcbd5 100644 --- a/tools/intellij-plugin/run/projects/test-project/src/main/kotlin/org/example/myplugin/MyPluginMain.kt +++ b/tools/intellij-plugin/run/projects/test-project/src/main/kotlin/org/example/myplugin/MyPluginMain.kt @@ -3,9 +3,25 @@ package org.example.myplugin import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin +val T = "scas" + "pp" // 编译期常量 + object MyPluginMain : KotlinPlugin( JvmPluginDescription( - "net.mamoe.main", + T, + "0.1.0", + ) { + name(".") + id("") + } +) { + fun test() { + + } +} + +object MyPluginMain2 : KotlinPlugin( + JvmPluginDescription( + "", "0.1.0", ) { name(".") diff --git a/tools/intellij-plugin/src/main/kotlin/net/mamoe/mirai/console/intellij/diagnostics/PluginDescriptionChecker.kt b/tools/intellij-plugin/src/main/kotlin/net/mamoe/mirai/console/intellij/diagnostics/PluginDescriptionChecker.kt index 5f8c0b64a..74f68de7b 100644 --- a/tools/intellij-plugin/src/main/kotlin/net/mamoe/mirai/console/intellij/diagnostics/PluginDescriptionChecker.kt +++ b/tools/intellij-plugin/src/main/kotlin/net/mamoe/mirai/console/intellij/diagnostics/PluginDescriptionChecker.kt @@ -13,7 +13,7 @@ import com.intellij.psi.PsiElement import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors import net.mamoe.mirai.console.compiler.common.resolve.ResolveContextKind import net.mamoe.mirai.console.compiler.common.resolve.resolveContextKind -import net.mamoe.mirai.console.intellij.resolve.findChildren +import net.mamoe.mirai.console.intellij.resolve.findChild import net.mamoe.mirai.console.intellij.resolve.resolveStringConstantValue import net.mamoe.mirai.console.intellij.resolve.valueParameters import org.jetbrains.kotlin.descriptors.DeclarationDescriptor @@ -36,28 +36,30 @@ class PluginDescriptionChecker : DeclarationChecker { private val ID_REGEX: Regex = Regex("""([a-zA-Z]+(?:\.[a-zA-Z0-9]+)*)\.([a-zA-Z]+(?:-[a-zA-Z0-9]+)*)""") private val FORBIDDEN_ID_NAMES: Array = arrayOf("main", "console", "plugin", "config", "data") + private const val syntax = """类似于 "net.mamoe.mirai.example-plugin", 其中 "net.mamoe.mirai" 为 groupId, "example-plugin" 为插件名. """ + fun checkPluginId(inspectionTarget: PsiElement, value: String): Diagnostic? { - if (value.isBlank()) return MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION.on(inspectionTarget, "Plugin id cannot be blank") + if (value.isBlank()) return MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION.on(inspectionTarget, "插件 Id 不能为空. \n插件 Id$syntax") if (value.none { it == '.' }) return MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION.on(inspectionTarget, - "'$value' is illegal. Plugin id must consist of both domain and name. ") + "插件 Id '$value' 无效. 插件 Id 必须同时包含 groupId 和插件名称. $syntax") val lowercaseId = value.toLowerCase() if (ID_REGEX.matchEntire(value) == null) { - return MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION.on(inspectionTarget, "Plugin does not match regex '${ID_REGEX.pattern}'.") + return MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION.on(inspectionTarget, "插件 Id 无效. 正确的插件 Id 应该满足正则表达式 '${ID_REGEX.pattern}', \n$syntax") } FORBIDDEN_ID_NAMES.firstOrNull { it == lowercaseId }?.let { illegal -> - return MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION.on(inspectionTarget, "Plugin id contains illegal word: '$illegal'.") + return MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION.on(inspectionTarget, "'$illegal' 不允许作为插件 Id. 确保插件 Id 不完全是这个名称.") } return null } fun checkPluginName(inspectionTarget: PsiElement, value: String): Diagnostic? { - if (value.isBlank()) return MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION.on(inspectionTarget, "Plugin name cannot be blank") + if (value.isBlank()) return MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION.on(inspectionTarget, "插件名不能为空.") val lowercaseName = value.toLowerCase() FORBIDDEN_ID_NAMES.firstOrNull { it == lowercaseName }?.let { illegal -> - return MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION.on(inspectionTarget, "Plugin name is illegal: '$illegal'.") + return MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION.on(inspectionTarget, "'$illegal' 不允许作为插件名. 确保插件名不完全是这个名称.") } return null } @@ -90,15 +92,13 @@ class PluginDescriptionChecker : DeclarationChecker { context: DeclarationCheckerContext, ) { val call = expression.calleeExpression.getResolvedCallOrResolveToCall(context) ?: return // unresolved - call.valueArgumentsByIndex?.forEach { resolvedValueArgument -> - for ((parameter, argument) in call.valueParameters.zip(resolvedValueArgument.arguments)) { - val parameterContextKind = parameter.resolveContextKind - if (checkersMap.containsKey(parameterContextKind)) { - val value = argument.getArgumentExpression() - ?.resolveStringConstantValue(context.bindingContext) ?: continue - for ((kind, fn) in checkersMap) { - if (parameterContextKind == kind) fn(argument.asElement(), value)?.let { context.report(it) } - } + for ((parameter, argument) in call.valueParameters.zip(call.valueArgumentsByIndex?.mapNotNull { it.arguments.firstOrNull() }.orEmpty())) { + val parameterContextKind = parameter.resolveContextKind + if (checkersMap.containsKey(parameterContextKind)) { + val value = argument.getArgumentExpression() + ?.resolveStringConstantValue(context.bindingContext) ?: continue + for ((kind, fn) in checkersMap) { + if (parameterContextKind == kind) fn(argument.asElement(), value)?.let { context.report(it) } } } } @@ -113,9 +113,9 @@ class PluginDescriptionChecker : DeclarationChecker { when (declaration) { is KtObjectDeclaration -> { // check super type constructor - val superTypeCallEntry = declaration.findChildren()?.findChildren() ?: return + val superTypeCallEntry = declaration.findChild()?.findChild() ?: return // val constructorCall = superTypeCallEntry.findChildren()?.resolveToCall() ?: return - val valueArgumentList = superTypeCallEntry.findChildren() ?: return + val valueArgumentList = superTypeCallEntry.findChild() ?: return valueArgumentList.arguments.asSequence().mapNotNull(KtValueArgument::getArgumentExpression).forEach { if (it.shouldPerformCheck()) { check(it as KtCallExpression, context) @@ -126,10 +126,10 @@ class PluginDescriptionChecker : DeclarationChecker { is KtClassOrObject -> { // check constructor - val superTypeCallEntry = declaration.findChildren()?.findChildren() ?: return + val superTypeCallEntry = declaration.findChild()?.findChild() ?: return - val constructorCall = superTypeCallEntry.findChildren()?.resolveToCall() ?: return - val valueArgumentList = superTypeCallEntry.findChildren() ?: return + val constructorCall = superTypeCallEntry.findChild()?.resolveToCall() ?: return + val valueArgumentList = superTypeCallEntry.findChild() ?: return } diff --git a/tools/intellij-plugin/src/main/kotlin/net/mamoe/mirai/console/intellij/resolve/resolveIdea.kt b/tools/intellij-plugin/src/main/kotlin/net/mamoe/mirai/console/intellij/resolve/resolveIdea.kt index ee7acee78..b0c261942 100644 --- a/tools/intellij-plugin/src/main/kotlin/net/mamoe/mirai/console/intellij/resolve/resolveIdea.kt +++ b/tools/intellij-plugin/src/main/kotlin/net/mamoe/mirai/console/intellij/resolve/resolveIdea.kt @@ -9,6 +9,7 @@ package net.mamoe.mirai.console.intellij.resolve +import com.intellij.psi.PsiDeclarationStatement import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import net.mamoe.mirai.console.compiler.common.castOrNull @@ -19,6 +20,8 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.VariableDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName +import org.jetbrains.kotlin.idea.references.KtSimpleNameReference +import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.nj2k.postProcessing.resolve import org.jetbrains.kotlin.psi.* @@ -28,6 +31,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.constants.StringValue import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance /** @@ -98,7 +102,7 @@ val PsiElement.allChildrenFlat: Sequence } } -inline fun PsiElement.findChildren(): E? = this.children.find { it is E } as E? +inline fun PsiElement.findChild(): E? = this.children.find { it is E } as E? fun KtElement?.getResolvedCallOrResolveToCall( context: BindingContext, @@ -111,10 +115,23 @@ val ResolvedCall.valueParameters: List { + when (val reference = references.firstIsInstance().resolve()) { + is KtDeclaration -> { + val descriptor = reference.descriptor.castOrNull() ?: return null + val compileTimeConstant = descriptor.compileTimeInitializer ?: return null + return compileTimeConstant.castOrNull()?.value + } + is PsiDeclarationStatement -> { + + } + } + } is KtStringTemplateExpression -> { if (hasInterpolation()) return null return entries.joinToString("") { it.text } } + /* is KtCallExpression -> { val callee = this.calleeExpression?.getResolvedCallOrResolveToCall(bindingContext)?.resultingDescriptor if (callee is VariableDescriptor) { @@ -122,7 +139,7 @@ fun KtExpression.resolveStringConstantValue(bindingContext: BindingContext): Str return compileTimeConstant.castOrNull()?.value } return null - } + }*/ is KtConstantExpression -> { // TODO: 2020/9/18 KtExpression.resolveStringConstantValue: KtConstantExpression }