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.diagnostics.Severity.ERROR
|
||||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
|
import org.jetbrains.kotlin.psi.KtTypeProjection
|
||||||
|
|
||||||
object MiraiConsoleErrors {
|
object MiraiConsoleErrors {
|
||||||
@JvmField
|
@JvmField
|
||||||
val ILLEGAL_PLUGIN_DESCRIPTION = create<PsiElement, String>(ERROR)
|
val ILLEGAL_PLUGIN_DESCRIPTION = create<PsiElement, String>(ERROR)
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val NOT_CONSTRUCTABLE_TYPE = create<PsiElement, KtCallExpression, String>(ERROR)
|
val NOT_CONSTRUCTABLE_TYPE = create<KtTypeProjection, KtCallExpression, String>(ERROR)
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val UNSERIALIZABLE_TYPE = create<PsiElement, ClassDescriptor>(ERROR)
|
val UNSERIALIZABLE_TYPE = create<PsiElement, ClassDescriptor>(ERROR)
|
||||||
|
@ -32,7 +32,8 @@ object MiraiConsoleErrorsRendering : DefaultErrorMessages.Extension {
|
|||||||
|
|
||||||
put(
|
put(
|
||||||
NOT_CONSTRUCTABLE_TYPE,
|
NOT_CONSTRUCTABLE_TYPE,
|
||||||
"类型 ''{0}'' 无法通过反射直接构造, 需要提供默认值.",
|
"类型 ''{1}'' 无法通过反射直接构造, 需要提供默认值.",
|
||||||
|
Renderers.EMPTY,
|
||||||
Renderers.STRING,
|
Renderers.STRING,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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.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
|
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"
|
val y = "傻逼 yellow"
|
@ -14,4 +14,18 @@ object MySimpleCommand000 : SimpleCommand(
|
|||||||
suspend fun CommandSender.handle(int: Int, str: String) {
|
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 com.intellij.codeInsight.intention.IntentionAction
|
||||||
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors
|
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.AddSerializerFix
|
||||||
|
import net.mamoe.mirai.console.intellij.diagnostics.fix.ProvideDefaultValueFix
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
||||||
import org.jetbrains.kotlin.idea.quickfix.KotlinIntentionActionsFactory
|
import org.jetbrains.kotlin.idea.quickfix.KotlinIntentionActionsFactory
|
||||||
import org.jetbrains.kotlin.idea.quickfix.QuickFixContributor
|
import org.jetbrains.kotlin.idea.quickfix.QuickFixContributor
|
||||||
@ -29,5 +30,6 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MiraiConsoleErrors.UNSERIALIZABLE_TYPE.registerFactory(AddSerializerFix)
|
MiraiConsoleErrors.UNSERIALIZABLE_TYPE.registerFactory(AddSerializerFix)
|
||||||
|
MiraiConsoleErrors.NOT_CONSTRUCTABLE_TYPE.registerFactory(ProvideDefaultValueFix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.console.intellij.diagnostics
|
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.SERIALIZABLE_FQ_NAME
|
||||||
import net.mamoe.mirai.console.compiler.common.castOrNull
|
import net.mamoe.mirai.console.compiler.common.castOrNull
|
||||||
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors
|
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors
|
||||||
@ -42,10 +41,10 @@ class PluginDataValuesChecker : DeclarationChecker {
|
|||||||
val (_, type) = e
|
val (_, type) = e
|
||||||
val classDescriptor = type.constructor.declarationDescriptor?.castOrNull<ClassDescriptor>()
|
val classDescriptor = type.constructor.declarationDescriptor?.castOrNull<ClassDescriptor>()
|
||||||
|
|
||||||
val inspectionTarget: PsiElement by lazy {
|
val inspectionTarget = kotlin.run {
|
||||||
val fqName = type.fqName ?: return@lazy callExpr
|
val fqName = type.fqName ?: return@run null
|
||||||
callExpr.typeArguments.find { it.typeReference?.isReferencing(fqName) == true } ?: callExpr
|
callExpr.typeArguments.find { it.typeReference?.isReferencing(fqName) == true }
|
||||||
}
|
} ?: return@forEach
|
||||||
|
|
||||||
if (classDescriptor == null
|
if (classDescriptor == null
|
||||||
|| !classDescriptor.hasNoArgConstructor()
|
|| !classDescriptor.hasNoArgConstructor()
|
||||||
|
@ -38,4 +38,6 @@ fun KtTypeReference.isReferencing(fqName: FqName): Boolean {
|
|||||||
return resolveReferencedType()?.getKotlinFqName() == fqName
|
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