mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-10 18:40:15 +08:00
Support UNSERIALIZABLE_TYPE for detecting @Serializable
annotations
This commit is contained in:
parent
7244cb76c4
commit
39145634e6
@ -18,6 +18,7 @@ import static org.jetbrains.kotlin.diagnostics.Severity.ERROR;
|
||||
public interface MiraiConsoleErrors {
|
||||
DiagnosticFactory1<PsiElement, String> ILLEGAL_PLUGIN_DESCRIPTION = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> NOT_CONSTRUCTABLE_TYPE = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> UNSERIALIZABLE_TYPE = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
@Deprecated
|
||||
Object _init = new Object() {
|
||||
|
@ -9,8 +9,7 @@
|
||||
|
||||
package net.mamoe.mirai.console.compiler.common.diagnostics
|
||||
|
||||
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION
|
||||
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.NOT_CONSTRUCTABLE_TYPE
|
||||
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.*
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.Renderers
|
||||
@ -28,6 +27,12 @@ object MiraiConsoleErrorsRendering : DefaultErrorMessages.Extension {
|
||||
"类型 {0} 无法通过反射直接构造, 需要提供默认值.",
|
||||
Renderers.STRING
|
||||
)
|
||||
|
||||
put(
|
||||
UNSERIALIZABLE_TYPE,
|
||||
"类型 {0} 无法被自动序列化, 需要添加序列化器",
|
||||
Renderers.STRING
|
||||
)
|
||||
}
|
||||
|
||||
override fun getMap() = MAP
|
||||
|
@ -9,8 +9,10 @@
|
||||
|
||||
package net.mamoe.mirai.console.compiler.common
|
||||
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import kotlin.contracts.contract
|
||||
|
||||
val SERIALIZABLE_FQ_NAME = FqName("kotlinx.serialization.Serializable")
|
||||
|
||||
fun <K, V> Map<K, V>.firstValue(): V = this.entries.first().value
|
||||
fun <K, V> Map<K, V>.firstKey(): K = this.entries.first().key
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.example.myplugin
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import net.mamoe.mirai.console.data.AutoSavePluginConfig
|
||||
import net.mamoe.mirai.console.data.value
|
||||
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
|
||||
@ -26,6 +27,7 @@ object DataTest : AutoSavePluginConfig() {
|
||||
val pp by value<NoDefaultValue>()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class HasDefaultValue(
|
||||
val x: Int = 0,
|
||||
)
|
||||
|
@ -10,12 +10,10 @@
|
||||
package net.mamoe.mirai.console.intellij.diagnostics
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import net.mamoe.mirai.console.compiler.common.SERIALIZABLE_FQ_NAME
|
||||
import net.mamoe.mirai.console.compiler.common.castOrNull
|
||||
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors
|
||||
import net.mamoe.mirai.console.compiler.common.resolve.PLUGIN_DATA_VALUE_FUNCTIONS_FQ_FQ_NAME
|
||||
import net.mamoe.mirai.console.compiler.common.resolve.ResolveContextKind
|
||||
import net.mamoe.mirai.console.compiler.common.resolve.hasNoArgConstructor
|
||||
import net.mamoe.mirai.console.compiler.common.resolve.resolveContextKind
|
||||
import net.mamoe.mirai.console.compiler.common.resolve.*
|
||||
import net.mamoe.mirai.console.intellij.resolve.resolveAllCallsWithElement
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
@ -41,24 +39,25 @@ class PluginDataValuesChecker : DeclarationChecker {
|
||||
(p.isReified || p.resolveContextKind == ResolveContextKind.RESTRICTED_NO_ARG_CONSTRUCTOR)
|
||||
&& t is SimpleType
|
||||
}.forEach { (e, callExpr) ->
|
||||
val (_, t) = e
|
||||
val classDescriptor = t.constructor.declarationDescriptor?.castOrNull<ClassDescriptor>()
|
||||
val (_, type) = e
|
||||
val classDescriptor = type.constructor.declarationDescriptor?.castOrNull<ClassDescriptor>()
|
||||
|
||||
fun getInspectionTarget(): PsiElement {
|
||||
return callExpr.typeArguments.find { it.references.firstOrNull()?.canonicalText == t.fqName?.toString() } ?: callExpr
|
||||
val inspectionTarget: PsiElement by lazy {
|
||||
callExpr.typeArguments.find { it.references.firstOrNull()?.canonicalText == type.fqName?.toString() } ?: callExpr
|
||||
}
|
||||
|
||||
fun reportInspection() {
|
||||
context.report(MiraiConsoleErrors.NOT_CONSTRUCTABLE_TYPE.on(
|
||||
getInspectionTarget(),
|
||||
t.fqName?.asString().toString())
|
||||
if (classDescriptor == null
|
||||
|| !classDescriptor.hasNoArgConstructor()
|
||||
) return@forEach context.report(MiraiConsoleErrors.NOT_CONSTRUCTABLE_TYPE.on(
|
||||
inspectionTarget,
|
||||
type.fqName?.asString().toString())
|
||||
)
|
||||
|
||||
if (!classDescriptor.hasAnnotation(SERIALIZABLE_FQ_NAME)) // TODO: 2020/9/18 external serializers
|
||||
return@forEach context.report(MiraiConsoleErrors.UNSERIALIZABLE_TYPE.on(
|
||||
inspectionTarget,
|
||||
type.fqName?.asString().toString())
|
||||
)
|
||||
}
|
||||
|
||||
when {
|
||||
classDescriptor == null -> reportInspection()
|
||||
!classDescriptor.hasNoArgConstructor() -> reportInspection()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user