New inspection: RESTRICTED_CONSOLE_COMMAND_OWNER, close #216

This commit is contained in:
Him188 2020-11-29 16:12:49 +08:00
parent bc290f63bb
commit a66ecbf8c8
18 changed files with 96 additions and 63 deletions

View File

@ -16,6 +16,7 @@ import net.mamoe.mirai.console.command.descriptor.CommandSignature
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
import net.mamoe.mirai.console.compiler.common.ResolveContext import net.mamoe.mirai.console.compiler.common.ResolveContext
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.RESTRICTED_CONSOLE_COMMAND_OWNER
import net.mamoe.mirai.console.permission.Permission import net.mamoe.mirai.console.permission.Permission
import net.mamoe.mirai.console.permission.PermissionId import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.console.util.ConsoleExperimentalApi import net.mamoe.mirai.console.util.ConsoleExperimentalApi
@ -89,6 +90,7 @@ public interface Command {
* 指令拥有者. * 指令拥有者.
* @see CommandOwner * @see CommandOwner
*/ */
@ResolveContext(RESTRICTED_CONSOLE_COMMAND_OWNER)
public val owner: CommandOwner public val owner: CommandOwner
public companion object { public companion object {

View File

@ -20,6 +20,7 @@ package net.mamoe.mirai.console.command
import net.mamoe.mirai.console.command.descriptor.* import net.mamoe.mirai.console.command.descriptor.*
import net.mamoe.mirai.console.compiler.common.ResolveContext import net.mamoe.mirai.console.compiler.common.ResolveContext
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.RESTRICTED_CONSOLE_COMMAND_OWNER
import net.mamoe.mirai.console.internal.command.CommandReflector import net.mamoe.mirai.console.internal.command.CommandReflector
import net.mamoe.mirai.console.internal.command.CompositeCommandSubCommandAnnotationResolver import net.mamoe.mirai.console.internal.command.CompositeCommandSubCommandAnnotationResolver
import net.mamoe.mirai.console.permission.Permission import net.mamoe.mirai.console.permission.Permission
@ -82,7 +83,7 @@ import kotlin.annotation.AnnotationTarget.FUNCTION
* @see buildCommandArgumentContext * @see buildCommandArgumentContext
*/ */
public abstract class CompositeCommand( public abstract class CompositeCommand(
owner: CommandOwner, @ResolveContext(RESTRICTED_CONSOLE_COMMAND_OWNER) owner: CommandOwner,
@ResolveContext(COMMAND_NAME) primaryName: String, @ResolveContext(COMMAND_NAME) primaryName: String,
@ResolveContext(COMMAND_NAME) vararg secondaryNames: String, @ResolveContext(COMMAND_NAME) vararg secondaryNames: String,
description: String = "no description available", description: String = "no description available",

View File

@ -15,6 +15,7 @@ import net.mamoe.mirai.console.command.descriptor.*
import net.mamoe.mirai.console.command.java.JRawCommand import net.mamoe.mirai.console.command.java.JRawCommand
import net.mamoe.mirai.console.compiler.common.ResolveContext import net.mamoe.mirai.console.compiler.common.ResolveContext
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.RESTRICTED_CONSOLE_COMMAND_OWNER
import net.mamoe.mirai.console.internal.command.findOrCreateCommandPermission import net.mamoe.mirai.console.internal.command.findOrCreateCommandPermission
import net.mamoe.mirai.console.internal.data.typeOf0 import net.mamoe.mirai.console.internal.data.typeOf0
import net.mamoe.mirai.console.permission.Permission import net.mamoe.mirai.console.permission.Permission
@ -38,11 +39,14 @@ public abstract class RawCommand(
* 指令拥有者. * 指令拥有者.
* @see CommandOwner * @see CommandOwner
*/ */
@ResolveContext(RESTRICTED_CONSOLE_COMMAND_OWNER)
public override val owner: CommandOwner, public override val owner: CommandOwner,
/** 主指令名. */ /** 主指令名. */
@ResolveContext(COMMAND_NAME) public override val primaryName: String, @ResolveContext(COMMAND_NAME)
public override val primaryName: String,
/** 次要指令名. */ /** 次要指令名. */
@ResolveContext(COMMAND_NAME) public override vararg val secondaryNames: String, @ResolveContext(COMMAND_NAME)
public override vararg val secondaryNames: String,
/** 用法说明, 用于发送给用户 */ /** 用法说明, 用于发送给用户 */
public override val usage: String = "<no usages given>", public override val usage: String = "<no usages given>",
/** 指令描述, 用于显示在 [BuiltInCommands.HelpCommand] */ /** 指令描述, 用于显示在 [BuiltInCommands.HelpCommand] */

View File

@ -21,6 +21,7 @@ import net.mamoe.mirai.console.command.descriptor.*
import net.mamoe.mirai.console.command.java.JSimpleCommand import net.mamoe.mirai.console.command.java.JSimpleCommand
import net.mamoe.mirai.console.compiler.common.ResolveContext import net.mamoe.mirai.console.compiler.common.ResolveContext
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.RESTRICTED_CONSOLE_COMMAND_OWNER
import net.mamoe.mirai.console.internal.command.CommandReflector import net.mamoe.mirai.console.internal.command.CommandReflector
import net.mamoe.mirai.console.internal.command.IllegalCommandDeclarationException import net.mamoe.mirai.console.internal.command.IllegalCommandDeclarationException
import net.mamoe.mirai.console.internal.command.SimpleCommandSubCommandAnnotationResolver import net.mamoe.mirai.console.internal.command.SimpleCommandSubCommandAnnotationResolver
@ -53,7 +54,7 @@ import kotlin.annotation.AnnotationTarget.VALUE_PARAMETER
* @see [CommandManager.executeCommand] * @see [CommandManager.executeCommand]
*/ */
public abstract class SimpleCommand( public abstract class SimpleCommand(
owner: CommandOwner, @ResolveContext(RESTRICTED_CONSOLE_COMMAND_OWNER) owner: CommandOwner,
@ResolveContext(COMMAND_NAME) primaryName: String, @ResolveContext(COMMAND_NAME) primaryName: String,
@ResolveContext(COMMAND_NAME) vararg secondaryNames: String, @ResolveContext(COMMAND_NAME) vararg secondaryNames: String,
description: String = "no description available", description: String = "no description available",

View File

@ -17,6 +17,7 @@ import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
import net.mamoe.mirai.console.command.descriptor.buildCommandArgumentContext import net.mamoe.mirai.console.command.descriptor.buildCommandArgumentContext
import net.mamoe.mirai.console.compiler.common.ResolveContext import net.mamoe.mirai.console.compiler.common.ResolveContext
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.RESTRICTED_CONSOLE_COMMAND_OWNER
import net.mamoe.mirai.console.permission.Permission import net.mamoe.mirai.console.permission.Permission
/** /**
@ -71,7 +72,7 @@ import net.mamoe.mirai.console.permission.Permission
*/ */
public abstract class JCompositeCommand public abstract class JCompositeCommand
@JvmOverloads constructor( @JvmOverloads constructor(
owner: CommandOwner, @ResolveContext(RESTRICTED_CONSOLE_COMMAND_OWNER) owner: CommandOwner,
@ResolveContext(COMMAND_NAME) primaryName: String, @ResolveContext(COMMAND_NAME) primaryName: String,
@ResolveContext(COMMAND_NAME) vararg secondaryNames: String, @ResolveContext(COMMAND_NAME) vararg secondaryNames: String,
parentPermission: Permission = owner.parentPermission, parentPermission: Permission = owner.parentPermission,

View File

@ -16,6 +16,7 @@ import net.mamoe.mirai.console.command.CommandOwner
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
import net.mamoe.mirai.console.compiler.common.ResolveContext import net.mamoe.mirai.console.compiler.common.ResolveContext
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.RESTRICTED_CONSOLE_COMMAND_OWNER
import net.mamoe.mirai.console.internal.command.findOrCreateCommandPermission import net.mamoe.mirai.console.internal.command.findOrCreateCommandPermission
import net.mamoe.mirai.console.permission.Permission import net.mamoe.mirai.console.permission.Permission
@ -51,9 +52,12 @@ public abstract class JRawCommand
* 指令拥有者. * 指令拥有者.
* @see CommandOwner * @see CommandOwner
*/ */
@ResolveContext(RESTRICTED_CONSOLE_COMMAND_OWNER)
public override val owner: CommandOwner, public override val owner: CommandOwner,
@ResolveContext(COMMAND_NAME) public override val primaryName: String, @ResolveContext(COMMAND_NAME)
@ResolveContext(COMMAND_NAME) public override vararg val secondaryNames: String, public override val primaryName: String,
@ResolveContext(COMMAND_NAME)
public override vararg val secondaryNames: String,
parentPermission: Permission = owner.parentPermission, parentPermission: Permission = owner.parentPermission,
) : Command { ) : Command {
/** 用法说明, 用于发送给用户 */ /** 用法说明, 用于发送给用户 */

View File

@ -16,6 +16,7 @@ import net.mamoe.mirai.console.command.descriptor.CommandArgumentContext
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
import net.mamoe.mirai.console.compiler.common.ResolveContext import net.mamoe.mirai.console.compiler.common.ResolveContext
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.COMMAND_NAME
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.RESTRICTED_CONSOLE_COMMAND_OWNER
import net.mamoe.mirai.console.permission.Permission import net.mamoe.mirai.console.permission.Permission
/** /**
@ -43,7 +44,7 @@ import net.mamoe.mirai.console.permission.Permission
* @see [CommandManager.executeCommand] * @see [CommandManager.executeCommand]
*/ */
public abstract class JSimpleCommand( public abstract class JSimpleCommand(
owner: CommandOwner, @ResolveContext(RESTRICTED_CONSOLE_COMMAND_OWNER) owner: CommandOwner,
@ResolveContext(COMMAND_NAME) primaryName: String, @ResolveContext(COMMAND_NAME) primaryName: String,
@ResolveContext(COMMAND_NAME) vararg secondaryNames: String, @ResolveContext(COMMAND_NAME) vararg secondaryNames: String,
basePermission: Permission, basePermission: Permission,

View File

@ -59,7 +59,7 @@ public annotation class ResolveContext(
/** /**
* @see SemVersion.Companion.parseRangeRequirement * @see SemVersion.Companion.parseRangeRequirement
*/ */
VERSION_REQUIREMENT, // ILLEGAL_VERSION_REQUIREMENT // TODO VERSION_REQUIREMENT, // ILLEGAL_VERSION_REQUIREMENT
/** /**
* @see Command.allNames * @see Command.allNames
@ -87,5 +87,7 @@ public annotation class ResolveContext(
* @see PluginData.value * @see PluginData.value
*/ */
RESTRICTED_NO_ARG_CONSTRUCTOR, // NOT_CONSTRUCTABLE_TYPE RESTRICTED_NO_ARG_CONSTRUCTOR, // NOT_CONSTRUCTABLE_TYPE
RESTRICTED_CONSOLE_COMMAND_OWNER,
} }
} }

View File

@ -11,7 +11,7 @@
object Versions { object Versions {
const val core = "1.3.3" const val core = "1.3.3"
const val console = "1.1.0-dev-30" const val console = "1.1.0-dev-32"
const val consoleGraphical = "0.0.7" const val consoleGraphical = "0.0.7"
const val consoleTerminal = console const val consoleTerminal = console

View File

@ -15,10 +15,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1.create
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory2.create import org.jetbrains.kotlin.diagnostics.DiagnosticFactory2.create
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.Severity.ERROR import org.jetbrains.kotlin.diagnostics.Severity.ERROR
import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtTypeProjection
import org.jetbrains.kotlin.psi.KtTypeReference
/** /**
* 如何增加一个错误: * 如何增加一个错误:
@ -59,6 +56,9 @@ object MiraiConsoleErrors {
// @JvmField // @JvmField
// val INAPPLICABLE_COMMAND_ANNOTATION = create<PsiElement, String>(ERROR) // val INAPPLICABLE_COMMAND_ANNOTATION = create<PsiElement, String>(ERROR)
@JvmField
val RESTRICTED_CONSOLE_COMMAND_OWNER = create<KtElement>(ERROR)
@JvmField @JvmField
val ILLEGAL_COMMAND_DECLARATION_RECEIVER = create<KtTypeReference>(ERROR) val ILLEGAL_COMMAND_DECLARATION_RECEIVER = create<KtTypeReference>(ERROR)

View File

@ -19,6 +19,7 @@ import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.IL
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.ILLEGAL_VERSION_REQUIREMENT import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.ILLEGAL_VERSION_REQUIREMENT
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.NOT_CONSTRUCTABLE_TYPE import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.NOT_CONSTRUCTABLE_TYPE
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.RESTRICTED_CONSOLE_COMMAND_OWNER
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.UNSERIALIZABLE_TYPE import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.UNSERIALIZABLE_TYPE
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap
@ -102,6 +103,11 @@ object MiraiConsoleErrorsRendering : DefaultErrorMessages.Extension {
"指令函数的接收者参数必须为 CommandSender 及其子类或无接收者.", "指令函数的接收者参数必须为 CommandSender 及其子类或无接收者.",
) )
put(
RESTRICTED_CONSOLE_COMMAND_OWNER,
"插件不允许使用 ConsoleCommandOwner 构造指令, 请使用插件主类作为 CommandOwner",
)
// put( // put(
// INAPPLICABLE_COMMAND_ANNOTATION, // INAPPLICABLE_COMMAND_ANNOTATION,
// "''{0}'' 无法在顶层函数使用.", // "''{0}'' 无法在顶层函数使用.",

View File

@ -33,6 +33,7 @@ val AUTO_SERVICE = FqName("com.google.auto.service.AutoService")
val COMPOSITE_COMMAND_SUB_COMMAND_FQ_NAME = FqName("net.mamoe.mirai.console.command.CompositeCommand.SubCommand") val COMPOSITE_COMMAND_SUB_COMMAND_FQ_NAME = FqName("net.mamoe.mirai.console.command.CompositeCommand.SubCommand")
val SIMPLE_COMMAND_HANDLER_COMMAND_FQ_NAME = FqName("net.mamoe.mirai.console.command.SimpleCommand.Handler") val SIMPLE_COMMAND_HANDLER_COMMAND_FQ_NAME = FqName("net.mamoe.mirai.console.command.SimpleCommand.Handler")
val COMMAND_SENDER_FQ_NAME = FqName("net.mamoe.mirai.console.command.CommandSender") val COMMAND_SENDER_FQ_NAME = FqName("net.mamoe.mirai.console.command.CommandSender")
val CONSOLE_COMMAND_SENDER_FQ_NAME = FqName("net.mamoe.mirai.console.command.ConsoleCommandSender")
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Plugin // Plugin
@ -70,7 +71,8 @@ enum class ResolveContextKind {
PERMISSION_NAME, PERMISSION_NAME,
PERMISSION_ID, PERMISSION_ID,
RESTRICTED_NO_ARG_CONSTRUCTOR RESTRICTED_NO_ARG_CONSTRUCTOR,
RESTRICTED_CONSOLE_COMMAND_OWNER,
; ;
companion object { companion object {

View File

@ -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 = "1.1.0-dev-30" // value is written here automatically during build const val CONSOLE_VERSION = "1.1.0-dev-32" // value is written here automatically during build
const val CORE_VERSION = "1.3.3" // value is written here automatically during build const val CORE_VERSION = "1.3.3" // value is written here automatically during build
} }

View File

@ -1,8 +1,7 @@
plugins { plugins {
kotlin("jvm") version "1.4.10" kotlin("jvm") version "1.4.20"
kotlin("plugin.serialization") version "1.4.10" kotlin("plugin.serialization") version "1.4.20"
kotlin("kapt") version "1.4.10" id("net.mamoe.mirai-console") version "1.1.0-dev-32"
id("com.github.johnrengelman.shadow") version "5.2.0"
} }
group = "org.example" group = "org.example"
@ -13,31 +12,3 @@ repositories {
jcenter() jcenter()
mavenCentral() mavenCentral()
} }
kotlin.sourceSets.all {
languageSettings.useExperimentalAnnotation("kotlin.RequiresOptIn")
}
dependencies {
compileOnly(kotlin("stdlib-jdk8"))
val core = "1.3.2"
val console = "1.0-RC-1"
compileOnly("net.mamoe:mirai-console:$console")
compileOnly("net.mamoe:mirai-core:$core")
val autoService = "1.0-rc7"
kapt("com.google.auto.service", "auto-service", autoService)
compileOnly("com.google.auto.service", "auto-service-annotations", autoService)
testImplementation("net.mamoe:mirai-console:$console")
testImplementation("net.mamoe:mirai-core:$core")
testImplementation("net.mamoe:mirai-console-terminal:$console")
testImplementation(kotlin("stdlib-jdk8"))
}
kotlin.target.compilations.all {
kotlinOptions.freeCompilerArgs += "-Xjvm-default=enable"
kotlinOptions.jvmTarget = "1.8"
}

View File

@ -1,2 +1,9 @@
rootProject.name = "test-project" rootProject.name = "test-project"
pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
jcenter()
}
}

View File

@ -2,12 +2,13 @@ package org.example.myplugin
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import net.mamoe.mirai.console.command.CommandSender import net.mamoe.mirai.console.command.CommandSender
import net.mamoe.mirai.console.command.ConsoleCommandOwner
import net.mamoe.mirai.console.command.SimpleCommand import net.mamoe.mirai.console.command.SimpleCommand
import net.mamoe.mirai.console.data.AutoSavePluginConfig import net.mamoe.mirai.console.data.AutoSavePluginConfig
import net.mamoe.mirai.console.data.value import net.mamoe.mirai.console.data.value
object MySimpleCommand000 : SimpleCommand( object MySimpleCommand000 : SimpleCommand(
MyPluginMain, "foo", ConsoleCommandOwner, "foo",
description = "示例指令" description = "示例指令"
) { ) {
@Handler @Handler

View File

@ -15,6 +15,8 @@ import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.IL
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.ILLEGAL_PERMISSION_NAMESPACE import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.ILLEGAL_PERMISSION_NAMESPACE
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.ILLEGAL_VERSION_REQUIREMENT import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.ILLEGAL_VERSION_REQUIREMENT
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.RESTRICTED_CONSOLE_COMMAND_OWNER
import net.mamoe.mirai.console.compiler.common.resolve.COMMAND_SENDER_FQ_NAME
import net.mamoe.mirai.console.compiler.common.resolve.ResolveContextKind import net.mamoe.mirai.console.compiler.common.resolve.ResolveContextKind
import net.mamoe.mirai.console.compiler.common.resolve.resolveContextKinds import net.mamoe.mirai.console.compiler.common.resolve.resolveContextKinds
import net.mamoe.mirai.console.intellij.resolve.resolveAllCalls import net.mamoe.mirai.console.intellij.resolve.resolveAllCalls
@ -24,9 +26,8 @@ import net.mamoe.mirai.console.intellij.util.RequirementHelper
import net.mamoe.mirai.console.intellij.util.RequirementParser import net.mamoe.mirai.console.intellij.util.RequirementParser
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.idea.inspections.collections.isCalling
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.ValueArgument
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
import java.util.* import java.util.*
@ -129,28 +130,44 @@ class ContextualParametersChecker : DeclarationChecker {
ILLEGAL_VERSION_REQUIREMENT.on(inspectionTarget, value, err.message ?: err.toString()) ILLEGAL_VERSION_REQUIREMENT.on(inspectionTarget, value, err.message ?: err.toString())
} }
} }
fun checkConsoleCommandOwner(context: DeclarationCheckerContext, inspectionTarget: KtElement, argument: ValueArgument): Diagnostic? {
val expr = argument.getArgumentExpression() ?: return null
if (expr is KtReferenceExpression) {
expr.getResolvedCall(context)?.isCalling(COMMAND_SENDER_FQ_NAME) ?: return null
}
return RESTRICTED_CONSOLE_COMMAND_OWNER.on(inspectionTarget)
}
} }
fun interface ElementChecker { fun interface ElementChecker {
operator fun invoke(declaration: KtElement, valueArgument: ValueArgument, value: String?): Diagnostic? operator fun invoke(context: DeclarationCheckerContext, declaration: KtElement, valueArgument: ValueArgument, value: String?): Diagnostic?
} }
private val stringCheckersMap: EnumMap<ResolveContextKind, ElementChecker> = private val checkersMap: EnumMap<ResolveContextKind, ElementChecker> =
EnumMap<ResolveContextKind, ElementChecker>(ResolveContextKind::class.java).apply { EnumMap<ResolveContextKind, ElementChecker>(ResolveContextKind::class.java).apply {
fun put(key: ResolveContextKind, value: KFunction2<KtElement, String, Diagnostic?>): ElementChecker? { fun put(key: ResolveContextKind, value: KFunction2<KtElement, String, Diagnostic?>): ElementChecker? {
return put(key) { d, _, v -> return put(key) { _, d, _, v ->
if (v != null) value(d, v) if (v != null) value(d, v)
else null else null
} }
} }
fun put(key: ResolveContextKind, value: KFunction2<KtElement, ValueArgument, Diagnostic?>): ElementChecker? { fun put(key: ResolveContextKind, value: KFunction2<KtElement, ValueArgument, Diagnostic?>): ElementChecker? {
return put(key) { d, v, _ -> return put(key) { _, d, v, _ ->
value(d, v) value(d, v)
} }
} }
fun put(key: ResolveContextKind, value: (DeclarationCheckerContext, KtElement, ValueArgument) -> Diagnostic?): ElementChecker? {
return put(key) { c, d, v, _ ->
value(c, d, v)
}
}
put(ResolveContextKind.PLUGIN_NAME, ::checkPluginName) put(ResolveContextKind.PLUGIN_NAME, ::checkPluginName)
put(ResolveContextKind.PLUGIN_ID, ::checkPluginId) put(ResolveContextKind.PLUGIN_ID, ::checkPluginId)
put(ResolveContextKind.SEMANTIC_VERSION, ::checkPluginVersion) put(ResolveContextKind.SEMANTIC_VERSION, ::checkPluginVersion)
@ -159,6 +176,7 @@ class ContextualParametersChecker : DeclarationChecker {
put(ResolveContextKind.PERMISSION_NAMESPACE, ::checkPermissionNamespace) put(ResolveContextKind.PERMISSION_NAMESPACE, ::checkPermissionNamespace)
put(ResolveContextKind.PERMISSION_ID, ::checkPermissionId) put(ResolveContextKind.PERMISSION_ID, ::checkPermissionId)
put(ResolveContextKind.VERSION_REQUIREMENT, ::checkVersionRequirement) put(ResolveContextKind.VERSION_REQUIREMENT, ::checkVersionRequirement)
put(ResolveContextKind.RESTRICTED_CONSOLE_COMMAND_OWNER, ::checkConsoleCommandOwner)
} }
override fun check( override fun check(
@ -166,6 +184,17 @@ class ContextualParametersChecker : DeclarationChecker {
descriptor: DeclarationDescriptor, descriptor: DeclarationDescriptor,
context: DeclarationCheckerContext, context: DeclarationCheckerContext,
) { ) {
when (declaration) {
is KtClassOrObject -> {
}
is KtNamedFunction -> {
}
}
declaration.resolveAllCalls(context.bindingContext) declaration.resolveAllCalls(context.bindingContext)
.asSequence() .asSequence()
.flatMap { call -> .flatMap { call ->
@ -173,7 +202,7 @@ class ContextualParametersChecker : DeclarationChecker {
} }
.mapNotNull { (p, a) -> .mapNotNull { (p, a) ->
p.resolveContextKinds p.resolveContextKinds
?.map(stringCheckersMap::get) ?.map(checkersMap::get)
?.mapNotNull { ?.mapNotNull {
if (it == null) null else it to a if (it == null) null else it to a
} }
@ -182,11 +211,12 @@ class ContextualParametersChecker : DeclarationChecker {
.mapNotNull { (kind, argument) -> .mapNotNull { (kind, argument) ->
Triple(kind, argument, argument.resolveStringConstantValues()) Triple(kind, argument, argument.resolveStringConstantValues())
} }
.forEach { (fn, argument, resolvedConstants) -> .forEach { (fn, argument, resolvedConstantsSequence) ->
if (resolvedConstants == null) { val resolvedConstants = resolvedConstantsSequence?.toList().orEmpty()
fn(argument.asElement(), argument, null)?.let { context.report(it) } if (resolvedConstants.isEmpty()) {
fn(context, argument.asElement(), argument, null)?.let { context.report(it) }
} else for (resolvedConstant in resolvedConstants) { } else for (resolvedConstant in resolvedConstants) {
fn(argument.asElement(), argument, resolvedConstant)?.let { context.report(it) } fn(context, argument.asElement(), argument, resolvedConstant)?.let { context.report(it) }
} }
} }
return return

View File

@ -123,8 +123,8 @@ fun KtAnnotated.hasAnnotation(fqName: FqName): Boolean =
fun KtDeclaration.resolveAllCalls(bindingContext: BindingContext): Sequence<ResolvedCall<*>> { fun KtDeclaration.resolveAllCalls(bindingContext: BindingContext): Sequence<ResolvedCall<*>> {
return allChildrenWithSelf return allChildrenWithSelf
.filterIsInstance<KtCallExpression>() .filterIsInstance<KtElement>()
.mapNotNull { it.calleeExpression?.getResolvedCall(bindingContext) } .mapNotNull { it.getResolvedCall(bindingContext) }
} }
fun KtDeclaration.resolveAllCallsWithElement(bindingContext: BindingContext): Sequence<Pair<ResolvedCall<out CallableDescriptor>, KtCallExpression>> { fun KtDeclaration.resolveAllCallsWithElement(bindingContext: BindingContext): Sequence<Pair<ResolvedCall<out CallableDescriptor>, KtCallExpression>> {