mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-10 18:40:15 +08:00
Support ProvideDefaultValueFix for NOT_CONSTRUCTABLE_TYPE
This commit is contained in:
parent
c077719c1b
commit
e37ac17b82
@ -16,13 +16,14 @@ import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.diagnostics.Severity.ERROR
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtTypeProjection
|
||||
|
||||
object MiraiConsoleErrors {
|
||||
@JvmField
|
||||
val ILLEGAL_PLUGIN_DESCRIPTION = create<PsiElement, String>(ERROR)
|
||||
|
||||
@JvmField
|
||||
val NOT_CONSTRUCTABLE_TYPE = create<PsiElement, KtCallExpression, String>(ERROR)
|
||||
val NOT_CONSTRUCTABLE_TYPE = create<KtTypeProjection, KtCallExpression, String>(ERROR)
|
||||
|
||||
@JvmField
|
||||
val UNSERIALIZABLE_TYPE = create<PsiElement, ClassDescriptor>(ERROR)
|
||||
|
@ -32,7 +32,8 @@ object MiraiConsoleErrorsRendering : DefaultErrorMessages.Extension {
|
||||
|
||||
put(
|
||||
NOT_CONSTRUCTABLE_TYPE,
|
||||
"类型 ''{0}'' 无法通过反射直接构造, 需要提供默认值.",
|
||||
"类型 ''{1}'' 无法通过反射直接构造, 需要提供默认值.",
|
||||
Renderers.EMPTY,
|
||||
Renderers.STRING,
|
||||
)
|
||||
|
||||
|
@ -10,6 +10,6 @@
|
||||
package net.mamoe.mirai.console.gradle
|
||||
|
||||
internal object VersionConstants {
|
||||
const val CONSOLE_VERSION = "1.0-RC2-dev-1" // value is written here automatically during build
|
||||
const val CONSOLE_VERSION = "1.0-RC2-dev-3" // value is written here automatically during build
|
||||
const val CORE_VERSION = "1.3.3" // value is written here automatically during build
|
||||
}
|
@ -31,17 +31,4 @@ object MyPluginMain : KotlinPlugin(
|
||||
}
|
||||
|
||||
|
||||
object DataTest : AutoSavePluginConfig("data") {
|
||||
val pp by value<NoDefaultValue>()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class HasDefaultValue(
|
||||
val x: Int = 0,
|
||||
)
|
||||
|
||||
data class NoDefaultValue(
|
||||
val y: Int,
|
||||
)
|
||||
|
||||
val y = "傻逼 yellow"
|
@ -14,4 +14,18 @@ object MySimpleCommand000 : SimpleCommand(
|
||||
suspend fun CommandSender.handle(int: Int, str: String) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object DataTest : AutoSavePluginConfig("data") {
|
||||
val pp by value<NoDefaultValue>(NoDefaultValue(1))
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class HasDefaultValue(
|
||||
val x: Int = 0,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class NoDefaultValue(
|
||||
val y: Int,
|
||||
)
|
||||
|
@ -12,6 +12,7 @@ package net.mamoe.mirai.console.intellij
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors
|
||||
import net.mamoe.mirai.console.intellij.diagnostics.fix.AddSerializerFix
|
||||
import net.mamoe.mirai.console.intellij.diagnostics.fix.ProvideDefaultValueFix
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinIntentionActionsFactory
|
||||
import org.jetbrains.kotlin.idea.quickfix.QuickFixContributor
|
||||
@ -29,5 +30,6 @@ class QuickFixRegistrar : QuickFixContributor {
|
||||
}
|
||||
|
||||
MiraiConsoleErrors.UNSERIALIZABLE_TYPE.registerFactory(AddSerializerFix)
|
||||
MiraiConsoleErrors.NOT_CONSTRUCTABLE_TYPE.registerFactory(ProvideDefaultValueFix)
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
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
|
||||
@ -42,10 +41,10 @@ class PluginDataValuesChecker : DeclarationChecker {
|
||||
val (_, type) = e
|
||||
val classDescriptor = type.constructor.declarationDescriptor?.castOrNull<ClassDescriptor>()
|
||||
|
||||
val inspectionTarget: PsiElement by lazy {
|
||||
val fqName = type.fqName ?: return@lazy callExpr
|
||||
callExpr.typeArguments.find { it.typeReference?.isReferencing(fqName) == true } ?: callExpr
|
||||
}
|
||||
val inspectionTarget = kotlin.run {
|
||||
val fqName = type.fqName ?: return@run null
|
||||
callExpr.typeArguments.find { it.typeReference?.isReferencing(fqName) == true }
|
||||
} ?: return@forEach
|
||||
|
||||
if (classDescriptor == null
|
||||
|| !classDescriptor.hasNoArgConstructor()
|
||||
|
@ -38,4 +38,6 @@ fun KtTypeReference.isReferencing(fqName: FqName): Boolean {
|
||||
return resolveReferencedType()?.getKotlinFqName() == fqName
|
||||
}
|
||||
|
||||
fun KtTypeReference.resolveReferencedType() = this.typeElement.castOrNull<KtUserType>()?.referenceExpression?.mainReference?.resolve()
|
||||
val KtTypeReference.referencedUserType: KtUserType? get() = this.typeElement.castOrNull()
|
||||
|
||||
fun KtTypeReference.resolveReferencedType() = referencedUserType?.referenceExpression?.mainReference?.resolve()
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.intellij.diagnostics.fix
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.SmartPointerManager
|
||||
import com.intellij.psi.SmartPsiElementPointer
|
||||
import net.mamoe.mirai.console.compiler.common.castOrNull
|
||||
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors
|
||||
import net.mamoe.mirai.console.intellij.resolve.findChild
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticWithParameters2
|
||||
import org.jetbrains.kotlin.idea.core.moveCaret
|
||||
import org.jetbrains.kotlin.idea.inspections.KotlinUniversalQuickFix
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinCrossLanguageQuickFixAction
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
|
||||
/**
|
||||
* @see MiraiConsoleErrors.NOT_CONSTRUCTABLE_TYPE
|
||||
*/
|
||||
class ProvideDefaultValueFix(
|
||||
element: KtCallExpression,
|
||||
private val typeProjection: SmartPsiElementPointer<KtTypeProjection>,
|
||||
) : KotlinCrossLanguageQuickFixAction<KtCallExpression>(element), KotlinUniversalQuickFix {
|
||||
|
||||
override fun getFamilyName(): String = "Mirai Console"
|
||||
override fun getText(): String = "添加默认值"
|
||||
|
||||
override fun invokeImpl(project: Project, editor: Editor?, file: PsiFile) {
|
||||
val element = element ?: return
|
||||
if (file !is KtFile) return
|
||||
|
||||
|
||||
/*
|
||||
val refereeFqName = element.resolve()?.getKotlinFqName() ?: return
|
||||
val referee = file.resolveImportReference(refereeFqName).singleOrNull { it is ClassDescriptor } ?: return
|
||||
ImportInsertHelper.getInstance(project).importDescriptor(file, referee)
|
||||
*/
|
||||
|
||||
val typeName = typeProjection.element?.typeReference?.typeElement?.castOrNull<KtUserType>()?.referencedName ?: return
|
||||
val argumentList = element.findChild<KtValueArgumentList>() ?: return
|
||||
val offset = argumentList.leftParenthesis?.endOffset ?: return
|
||||
|
||||
project.executeWriteCommand(name) {
|
||||
argumentList.addArgument(KtPsiFactory(project).createArgument("$typeName()"))
|
||||
editor?.moveCaret(offset + typeName.length + 1)
|
||||
}
|
||||
}
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||
val diagnostic1 = diagnostic.castOrNull<DiagnosticWithParameters2<KtTypeProjection, KtCallExpression, *>>() ?: return null
|
||||
return ProvideDefaultValueFix(diagnostic1.a, SmartPointerManager.createPointer(diagnostic1.psiElement))
|
||||
}
|
||||
|
||||
override fun isApplicableForCodeFragment(): Boolean = false
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user