diff --git a/tools/compiler-common/src/diagnostics/MiraiConsoleErrors.kt b/tools/compiler-common/src/diagnostics/MiraiConsoleErrors.kt index 4b604bcf8..7f2544a39 100644 --- a/tools/compiler-common/src/diagnostics/MiraiConsoleErrors.kt +++ b/tools/compiler-common/src/diagnostics/MiraiConsoleErrors.kt @@ -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(ERROR) @JvmField - val NOT_CONSTRUCTABLE_TYPE = create(ERROR) + val NOT_CONSTRUCTABLE_TYPE = create(ERROR) @JvmField val UNSERIALIZABLE_TYPE = create(ERROR) diff --git a/tools/compiler-common/src/diagnostics/MiraiConsoleErrorsRendering.kt b/tools/compiler-common/src/diagnostics/MiraiConsoleErrorsRendering.kt index 734a3a02a..effb040ff 100644 --- a/tools/compiler-common/src/diagnostics/MiraiConsoleErrorsRendering.kt +++ b/tools/compiler-common/src/diagnostics/MiraiConsoleErrorsRendering.kt @@ -32,7 +32,8 @@ object MiraiConsoleErrorsRendering : DefaultErrorMessages.Extension { put( NOT_CONSTRUCTABLE_TYPE, - "类型 ''{0}'' 无法通过反射直接构造, 需要提供默认值.", + "类型 ''{1}'' 无法通过反射直接构造, 需要提供默认值.", + Renderers.EMPTY, Renderers.STRING, ) diff --git a/tools/gradle-plugin/src/VersionConstants.kt b/tools/gradle-plugin/src/VersionConstants.kt index 1f9ccb633..3c742ce5a 100644 --- a/tools/gradle-plugin/src/VersionConstants.kt +++ b/tools/gradle-plugin/src/VersionConstants.kt @@ -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 } \ No newline at end of file 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 e59e512e3..9e148c27d 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 @@ -31,17 +31,4 @@ object MyPluginMain : KotlinPlugin( } -object DataTest : AutoSavePluginConfig("data") { - val pp by value() -} - -@Serializable -data class HasDefaultValue( - val x: Int = 0, -) - -data class NoDefaultValue( - val y: Int, -) - val y = "傻逼 yellow" \ No newline at end of file diff --git a/tools/intellij-plugin/run/projects/test-project/src/main/kotlin/org/example/myplugin/MySimpleCommand.kt b/tools/intellij-plugin/run/projects/test-project/src/main/kotlin/org/example/myplugin/MySimpleCommand.kt index 4e100351f..85199308a 100644 --- a/tools/intellij-plugin/run/projects/test-project/src/main/kotlin/org/example/myplugin/MySimpleCommand.kt +++ b/tools/intellij-plugin/run/projects/test-project/src/main/kotlin/org/example/myplugin/MySimpleCommand.kt @@ -14,4 +14,18 @@ object MySimpleCommand000 : SimpleCommand( suspend fun CommandSender.handle(int: Int, str: String) { } -} \ No newline at end of file +} + +object DataTest : AutoSavePluginConfig("data") { + val pp by value(NoDefaultValue(1)) +} + +@Serializable +data class HasDefaultValue( + val x: Int = 0, +) + +@Serializable +data class NoDefaultValue( + val y: Int, +) diff --git a/tools/intellij-plugin/src/QuickFixRegistrar.kt b/tools/intellij-plugin/src/QuickFixRegistrar.kt index 6e0bcccdc..e860ec0a0 100644 --- a/tools/intellij-plugin/src/QuickFixRegistrar.kt +++ b/tools/intellij-plugin/src/QuickFixRegistrar.kt @@ -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) } } diff --git a/tools/intellij-plugin/src/diagnostics/PluginDataValuesChecker.kt b/tools/intellij-plugin/src/diagnostics/PluginDataValuesChecker.kt index 274d7ea9c..7eb1c0f6b 100644 --- a/tools/intellij-plugin/src/diagnostics/PluginDataValuesChecker.kt +++ b/tools/intellij-plugin/src/diagnostics/PluginDataValuesChecker.kt @@ -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() - 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() diff --git a/tools/intellij-plugin/src/diagnostics/diagnosticsUtil.kt b/tools/intellij-plugin/src/diagnostics/diagnosticsUtil.kt index 9b615da46..86481de29 100644 --- a/tools/intellij-plugin/src/diagnostics/diagnosticsUtil.kt +++ b/tools/intellij-plugin/src/diagnostics/diagnosticsUtil.kt @@ -38,4 +38,6 @@ fun KtTypeReference.isReferencing(fqName: FqName): Boolean { return resolveReferencedType()?.getKotlinFqName() == fqName } -fun KtTypeReference.resolveReferencedType() = this.typeElement.castOrNull()?.referenceExpression?.mainReference?.resolve() \ No newline at end of file +val KtTypeReference.referencedUserType: KtUserType? get() = this.typeElement.castOrNull() + +fun KtTypeReference.resolveReferencedType() = referencedUserType?.referenceExpression?.mainReference?.resolve() \ No newline at end of file diff --git a/tools/intellij-plugin/src/diagnostics/fix/ProvideDefaultValueFix.kt b/tools/intellij-plugin/src/diagnostics/fix/ProvideDefaultValueFix.kt new file mode 100644 index 000000000..8ac8b20cb --- /dev/null +++ b/tools/intellij-plugin/src/diagnostics/fix/ProvideDefaultValueFix.kt @@ -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, +) : KotlinCrossLanguageQuickFixAction(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()?.referencedName ?: return + val argumentList = element.findChild() ?: 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>() ?: return null + return ProvideDefaultValueFix(diagnostic1.a, SmartPointerManager.createPointer(diagnostic1.psiElement)) + } + + override fun isApplicableForCodeFragment(): Boolean = false + } +}