mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-06 08:00:10 +08:00
New Project Wizard for IDEA 221 (#1979)
* NewProjectWizard * dependencies and validations * Implement checkers * Implement project generator * Add new template RunTerminal.run.xml for Run Configuration * Set supported IDEA version to 221 * Fix localization * Fix since-until * Rearrange files
This commit is contained in:
parent
15133c7902
commit
481973d5e6
@ -19,14 +19,14 @@ object Versions {
|
||||
|
||||
val core = project
|
||||
val console = project
|
||||
val consoleIntellij = "213-$project-160-1" // idea-mirai-kotlin-patch
|
||||
val consoleIntellij = "221-$project-162-1" // idea-mirai-kotlin-patch
|
||||
val consoleTerminal = project
|
||||
|
||||
const val kotlinCompiler = "1.6.0"
|
||||
const val kotlinStdlib = kotlinCompiler
|
||||
const val dokka = "1.6.0"
|
||||
|
||||
const val kotlinCompilerForIdeaPlugin = "1.6.20-M1"
|
||||
const val kotlinCompilerForIdeaPlugin = "1.6.20"
|
||||
|
||||
const val coroutines = "1.6.0"
|
||||
const val atomicFU = "0.17.0"
|
||||
@ -61,10 +61,10 @@ object Versions {
|
||||
// If you the versions below, you need to sync changes to mirai-console/buildSrc/src/main/kotlin/Versions.kt
|
||||
|
||||
const val yamlkt = "0.10.2"
|
||||
const val intellijGradlePlugin = "1.3.0"
|
||||
const val intellijGradlePlugin = "1.5.3"
|
||||
|
||||
// const val kotlinIntellijPlugin = "211-1.5.20-release-284-IJ7442.40" // keep to newest as kotlinCompiler
|
||||
const val intellij = "2021.3.2" // don't update easily unless you want your disk space -= 500MB
|
||||
const val intellij = "2022.1" // don't update easily unless you want your disk space -= 500MB
|
||||
|
||||
}
|
||||
|
||||
|
@ -71,8 +71,8 @@ kotlin.target.compilations.all {
|
||||
|
||||
// https://plugins.jetbrains.com/docs/intellij/kotlin.html#kotlin-standard-library
|
||||
tasks.withType<org.jetbrains.intellij.tasks.PatchPluginXmlTask> {
|
||||
sinceBuild.set("212.*")
|
||||
untilBuild.set("225.*")
|
||||
sinceBuild.set("221.0")
|
||||
untilBuild.set("221.999999")
|
||||
pluginDescription.set(
|
||||
"""
|
||||
Plugin development support for <a href='https://github.com/mamoe/mirai'>Mirai Console</a>
|
||||
|
@ -1,10 +1,10 @@
|
||||
<!--
|
||||
~ Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
~ Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
~ https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
-->
|
||||
|
||||
<idea-plugin>
|
||||
@ -25,9 +25,9 @@
|
||||
<depends>com.intellij.gradle</depends>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<moduleType id="MIRAI_MODULE_TYPE"
|
||||
implementationClass="net.mamoe.mirai.console.intellij.creator.MiraiModuleType"/>
|
||||
<moduleBuilder id="MIRAI_MODULE" builderClass="net.mamoe.mirai.console.intellij.creator.MiraiModuleBuilder"/>
|
||||
<moduleType id="MIRAI_CONSOLE_PLUGIN_MODULE"
|
||||
implementationClass="net.mamoe.mirai.console.intellij.wizard.MiraiModuleType"/>
|
||||
<moduleBuilder id="MIRAI_MODULE" builderClass="net.mamoe.mirai.console.intellij.wizard.MiraiModuleBuilder"/>
|
||||
|
||||
<fileTemplateGroup implementation="net.mamoe.mirai.console.intellij.assets.FileTemplateRegistrar"/>
|
||||
<codeInsight.lineMarkerProvider language="JAVA"
|
||||
|
@ -0,0 +1,14 @@
|
||||
<!--
|
||||
~ Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new .gitignore for Gradle projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!--
|
||||
~ Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new gradle.properties for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!--
|
||||
~ Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new build.gradle for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!--
|
||||
~ Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new build.gradle.kts for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!--
|
||||
~ Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new plugin main class for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!--
|
||||
~ Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new plugin main class for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1 @@
|
||||
${PACKAGE_NAME}.${CLASS_NAME}
|
@ -0,0 +1,14 @@
|
||||
<!--
|
||||
~ Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new plugin main class for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!--
|
||||
~ Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new settings.gradle.kts for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -1,20 +1,14 @@
|
||||
package $PACKAGE_NAME
|
||||
|
||||
import java.io.File
|
||||
import net.mamoe.mirai.alsoLogin
|
||||
import net.mamoe.mirai.console.MiraiConsole
|
||||
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.enable
|
||||
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.load
|
||||
import net.mamoe.mirai.console.terminal.MiraiConsoleTerminalLoader
|
||||
|
||||
fun setupWorkingDir() {
|
||||
// see: net.mamoe.mirai.console.terminal.MiraiConsoleImplementationTerminal
|
||||
System.setProperty("user.dir", File("debug-sandbox").absolutePath)
|
||||
}
|
||||
import java.io.File
|
||||
import java.util.Properties
|
||||
|
||||
suspend fun main() {
|
||||
setupWorkingDir()
|
||||
|
||||
MiraiConsoleTerminalLoader.startAsDaemon()
|
||||
|
||||
val pluginInstance = ${CLASS_NAME}#if (${LANGUAGE_TYPE} != "Kotlin").INSTANCE #end
|
||||
@ -23,7 +17,9 @@ suspend fun main() {
|
||||
pluginInstance.load() // 主动加载插件, Console 会调用 ${CLASS_NAME}.onLoad
|
||||
pluginInstance.enable() // 主动启用插件, Console 会调用 ${CLASS_NAME}.onEnable
|
||||
|
||||
val bot = MiraiConsole.addBot(123456, "").alsoLogin() // 登录一个测试环境的 Bot
|
||||
val properties = Properties().apply { File("account.properties").inputStream().use { load(it) } }
|
||||
|
||||
val bot = MiraiConsole.addBot(properties.getProperty("id").toLong(), properties.getProperty("password")).alsoLogin() // 登录一个测试环境的 Bot
|
||||
|
||||
MiraiConsole.job.join()
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<!--
|
||||
~ Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new settings.gradle.kts for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,11 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="RunTerminal" type="JetRunConfigurationType" nameIsGenerated="false">
|
||||
<option name="MAIN_CLASS_NAME" value="${PACKAGE_NAME}.RunTerminalKt"/>
|
||||
<module name="${MODULE_NAME}.test"/>
|
||||
<shortenClasspath name="NONE"/>
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/debug-sandbox"/>
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true"/>
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
@ -0,0 +1,14 @@
|
||||
<!--
|
||||
~ Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new settings.gradle.kts for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,2 @@
|
||||
id=123456
|
||||
password=pwd
|
@ -0,0 +1,14 @@
|
||||
<!--
|
||||
~ Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new gradle.properties for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -1,14 +0,0 @@
|
||||
<!--
|
||||
~ Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new .gitignore for Gradle projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -1,14 +0,0 @@
|
||||
<!--
|
||||
~ Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new gradle.properties for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -1,14 +0,0 @@
|
||||
<!--
|
||||
~ Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new build.gradle for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -1,14 +0,0 @@
|
||||
<!--
|
||||
~ Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new build.gradle.kts for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -1,14 +0,0 @@
|
||||
<!--
|
||||
~ Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new plugin main class for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -1,14 +0,0 @@
|
||||
<!--
|
||||
~ Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new plugin main class for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -1,14 +0,0 @@
|
||||
<!--
|
||||
~ Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new settings.gradle.kts for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -1,14 +0,0 @@
|
||||
<!--
|
||||
~ Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
~
|
||||
~ 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
~ Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
~
|
||||
~ https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
-->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This is a built-in file template used to create a new settings.gradle.kts for Mirai Console Plugin projects.</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,39 @@
|
||||
#
|
||||
# Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
#
|
||||
# ???????? GNU AFFERO GENERAL PUBLIC LICENSE version 3 ??????, ?????????????.
|
||||
# Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
#
|
||||
# https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
#
|
||||
module.presentation.name=Mirai Console Plugin
|
||||
module.description="Template for building plugins for <b>Mirai Console</b>"
|
||||
title.plugin.description=Plugin Description
|
||||
label.plugin.version=Plugin Version:
|
||||
label.version.stable=Stable
|
||||
label.version.prerelease=Prerelease
|
||||
label.version.nightly=Nightly
|
||||
label.plugin.id=Plugin ID:
|
||||
label.plugin.name=Plugin Name:
|
||||
label.mirai.version.loading=Loading...
|
||||
label.mirai.version=Mirai Version:
|
||||
error.failed.to.download.mirai.version=Failed to download version list, please select a version manually
|
||||
error.please.wait.for.mirai.version=Please wait for downloading version list
|
||||
label.plugin.author=Plugin Author:
|
||||
comment.plugin.id=Should consist of English characters and/or numbers, '.', ':', '-'. Example: "net.mamoe:chat-command".
|
||||
comment.plugin.name=Example: "Chat Command".
|
||||
comment.plugin.version=Should comply <a href="https://semver.org/">Semantic Versioning</a>, not including 'v'. Example: "0.1.0".
|
||||
comment.mirai.version=Minimum version of Mirai Console this plugin requires on.
|
||||
label.plugin.dependencies=Plugin Dependencies:
|
||||
label.plugin.info=Plugin Info:
|
||||
comment.plugin.dependencies=Each dependency is in format "id:VersionRequirement" (not including quotation marks). To declare optional dependency, add "?" at the end. \
|
||||
Example: "net.mamoe.chat-command:[1.0.0, 2.0.0)?" declares and optional dependency on "net.mamoe.chat-command", requiring its version to be greater or equal to 1.0.0 and smaller than 2.0.0. \
|
||||
Separate multiple dependencies into liens. \
|
||||
Syntax for "VersionRequirement" can be found at <a href="https://ant.apache.org/ivy/history/latest-milestone/settings/version-matchers.html">Apache Ivy version-matchers</a>.
|
||||
comment.plugin.info=Introductory information about this plugin.
|
||||
text.hint.plugin.info=Optional
|
||||
text.hint.plugin.dependencies=Optional
|
||||
validation.plugin.name.forbidden.character="{0}" is forbidden in plugin name
|
||||
validation.illegal.plugin.id=Invalid plugin id "{0}"
|
||||
validation.illegal.version=Invalid version.\n{0}
|
||||
no.error.message=No error message
|
@ -0,0 +1,39 @@
|
||||
#
|
||||
# Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
#
|
||||
# ???????? GNU AFFERO GENERAL PUBLIC LICENSE version 3 ??????, ?????????????.
|
||||
# Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
#
|
||||
# https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
#
|
||||
module.presentation.name=Mirai Console 插件
|
||||
module.description="构建 <b>Mirai Console</b> 插件的模板"
|
||||
title.plugin.description=插件信息
|
||||
label.plugin.version=插件版本号:
|
||||
label.version.stable=稳定版
|
||||
label.version.prerelease=预览版
|
||||
label.version.nightly=开发版
|
||||
label.plugin.id=插件 ID:
|
||||
label.plugin.name=插件名称:
|
||||
label.mirai.version.loading=加载中...
|
||||
label.mirai.version=Mirai 版本号:
|
||||
error.failed.to.download.mirai.version=下载版本列表失败, 请手动选择版本号
|
||||
error.please.wait.for.mirai.version=请等待下载版本列表
|
||||
label.plugin.author=插件作者:
|
||||
comment.plugin.id=只能包含以下内容: 英文字母, 数字, '.', ':', '-'. 示例: "net.mamoe.chat-command".
|
||||
comment.plugin.name=示例: "Chat Command".
|
||||
comment.plugin.version=需遵循 <a href="https://semver.org/">语义化版本</a>, 不包含 'v'. 示例: "0.1.0".
|
||||
comment.mirai.version=插件依赖的最低 Mirai Console 版本号
|
||||
label.plugin.dependencies=插件依赖:
|
||||
label.plugin.info=插件描述:
|
||||
comment.plugin.dependencies=每个依赖格式为 "id:版本要求" (不包括引号). 若要定义可选依赖, 请在末尾添加 "?". \
|
||||
示例: "net.mamoe.chat-command:[1.0.0, 2.0.0)?" 定义对 "net.mamoe.chat-command" 的可选依赖, 要求其版本大于或等于 1.0.0 且小于 2.0.0. \
|
||||
多个依赖以换行符分割. \
|
||||
"版本要求" 语法可在 <a href="https://ant.apache.org/ivy/history/latest-milestone/settings/version-matchers.html">Apache Ivy version-matchers</a> 查看.
|
||||
comment.plugin.info=对该插件的介绍信息.
|
||||
text.hint.plugin.info=可留空
|
||||
text.hint.plugin.dependencies=可留空
|
||||
validation.plugin.name.forbidden.character=插件名称中不允许存在 "{0}"
|
||||
validation.illegal.plugin.id=插件 ID 无效: "{0}"
|
||||
validation.illegal.version=插件版本无效\n{0}
|
||||
no.error.message=无错误信息
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.intellij.assets
|
||||
@ -31,7 +31,11 @@ object FT { // file template
|
||||
const val PluginMainKt = "Plugin main class Kotlin.kt"
|
||||
const val PluginMainJava = "Plugin main class Java.java"
|
||||
|
||||
const val PluginMainService = "Plugin main service.txt"
|
||||
|
||||
const val Gitignore = ".gitignore"
|
||||
|
||||
const val RunTerminal = "RunTerminal.kt"
|
||||
const val RunTerminalRun = "RunTerminal.run.xml"
|
||||
const val AccountProperties = "account.properties"
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ class FileTemplateRegistrar : com.intellij.ide.fileTemplates.FileTemplateGroupDe
|
||||
|
||||
addTemplate(FileTemplateDescriptor(FT.PluginMainKt))
|
||||
addTemplate(FileTemplateDescriptor(FT.PluginMainJava))
|
||||
addTemplate(FileTemplateDescriptor(FT.PluginMainService))
|
||||
|
||||
addTemplate(FileTemplateDescriptor(FT.GradleProperties))
|
||||
|
||||
@ -30,6 +31,7 @@ class FileTemplateRegistrar : com.intellij.ide.fileTemplates.FileTemplateGroupDe
|
||||
addTemplate(FileTemplateDescriptor(FT.Gitignore))
|
||||
|
||||
addTemplate(FileTemplateDescriptor(FT.RunTerminal))
|
||||
addTemplate(FileTemplateDescriptor(FT.RunTerminalRun))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
package net.mamoe.mirai.console.intellij.creator
|
||||
|
||||
import com.intellij.ide.util.projectWizard.JavaModuleBuilder
|
||||
import com.intellij.ide.util.projectWizard.ModuleWizardStep
|
||||
import com.intellij.ide.util.projectWizard.WizardContext
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.module.JavaModuleType
|
||||
import com.intellij.openapi.module.ModuleType
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.project.DumbAwareRunnable
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.roots.ModifiableRootModel
|
||||
import com.intellij.openapi.roots.ui.configuration.ModulesProvider
|
||||
import com.intellij.openapi.startup.StartupManager
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import net.mamoe.mirai.console.intellij.assets.Icons
|
||||
import net.mamoe.mirai.console.intellij.creator.steps.BuildSystemStep
|
||||
import net.mamoe.mirai.console.intellij.creator.steps.OptionsStep
|
||||
import net.mamoe.mirai.console.intellij.creator.steps.PluginCoordinatesStep
|
||||
import net.mamoe.mirai.console.intellij.creator.tasks.CreateProjectTask
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
class MiraiModuleBuilder : JavaModuleBuilder() {
|
||||
override fun getPresentableName() = MiraiModuleType.NAME
|
||||
override fun getNodeIcon() = Icons.MainIcon
|
||||
override fun getGroupName() = MiraiModuleType.NAME
|
||||
override fun getWeight() = BUILD_SYSTEM_WEIGHT - 1
|
||||
override fun getBuilderId() = ID
|
||||
override fun getModuleType(): ModuleType<*> = JavaModuleType.getModuleType()
|
||||
override fun getParentGroup() = MiraiModuleType.NAME
|
||||
|
||||
override fun setupRootModel(rootModel: ModifiableRootModel) {
|
||||
val project = rootModel.project
|
||||
val (root, vFile) = createAndGetRoot()
|
||||
rootModel.addContentEntry(vFile)
|
||||
|
||||
if (moduleJdk != null) {
|
||||
rootModel.sdk = moduleJdk
|
||||
} else {
|
||||
rootModel.inheritSdk()
|
||||
}
|
||||
|
||||
val r = DumbAwareRunnable {
|
||||
ProgressManager.getInstance().run(CreateProjectTask(root, rootModel.module, model))
|
||||
}
|
||||
|
||||
if (project.isDisposed) return
|
||||
|
||||
if (
|
||||
ApplicationManager.getApplication().isUnitTestMode ||
|
||||
ApplicationManager.getApplication().isHeadlessEnvironment
|
||||
) {
|
||||
r.run()
|
||||
return
|
||||
}
|
||||
|
||||
if (!project.isInitialized) {
|
||||
StartupManager.getInstance(project).registerPostStartupActivity(r)
|
||||
return
|
||||
}
|
||||
|
||||
DumbService.getInstance(project).runWhenSmart(r)
|
||||
}
|
||||
|
||||
private fun createAndGetRoot(): Pair<Path, VirtualFile> {
|
||||
val temp = contentEntryPath ?: throw IllegalStateException("Failed to get content entry path")
|
||||
|
||||
val pathName = FileUtil.toSystemIndependentName(temp)
|
||||
|
||||
val path = Paths.get(pathName)
|
||||
Files.createDirectories(path)
|
||||
val vFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(pathName)
|
||||
?: throw IllegalStateException("Failed to refresh and file file: $path")
|
||||
|
||||
|
||||
|
||||
return path to vFile
|
||||
}
|
||||
|
||||
// private val scope = CoroutineScope(SupervisorJob())
|
||||
private val scope = Executors.newFixedThreadPool(2)
|
||||
private val model = MiraiProjectModel.create(scope)
|
||||
|
||||
override fun cleanup() {
|
||||
super.cleanup()
|
||||
scope.shutdownNow()
|
||||
}
|
||||
|
||||
override fun createWizardSteps(
|
||||
wizardContext: WizardContext,
|
||||
modulesProvider: ModulesProvider
|
||||
): Array<ModuleWizardStep> {
|
||||
return arrayOf(
|
||||
BuildSystemStep(model),
|
||||
PluginCoordinatesStep(model, scope),
|
||||
)
|
||||
}
|
||||
|
||||
override fun getCustomOptionsStep(context: WizardContext?, parentDisposable: Disposable?): ModuleWizardStep =
|
||||
OptionsStep()
|
||||
|
||||
companion object {
|
||||
const val ID = "MIRAI_MODULE"
|
||||
}
|
||||
}
|
@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
package net.mamoe.mirai.console.intellij.creator
|
||||
|
||||
import net.mamoe.mirai.console.intellij.creator.steps.BuildSystemType
|
||||
import net.mamoe.mirai.console.intellij.creator.steps.LanguageType
|
||||
import net.mamoe.mirai.console.intellij.creator.tasks.adjustToClassName
|
||||
import net.mamoe.mirai.console.intellij.creator.tasks.lateinitReadWriteProperty
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.concurrent.ExecutorService
|
||||
import kotlin.contracts.contract
|
||||
|
||||
data class ProjectCoordinates(
|
||||
val groupId: String, // already checked by pattern
|
||||
val artifactId: String,
|
||||
val version: String
|
||||
) {
|
||||
val packageName: String get() = groupId
|
||||
}
|
||||
|
||||
data class PluginCoordinates(
|
||||
val id: String?,
|
||||
val name: String?,
|
||||
val author: String?,
|
||||
val info: String?,
|
||||
val dependsOn: String?,
|
||||
)
|
||||
|
||||
class MiraiProjectModel private constructor() {
|
||||
// STEP: ProjectCreator
|
||||
|
||||
var projectCoordinates: ProjectCoordinates? = null
|
||||
var buildSystemType: BuildSystemType = BuildSystemType.DEFAULT
|
||||
var languageType: LanguageType = LanguageType.DEFAULT
|
||||
|
||||
var miraiVersion: String? = null
|
||||
var pluginCoordinates: PluginCoordinates? = null
|
||||
|
||||
var mainClassQualifiedName: String by lateinitReadWriteProperty { "$packageName.$mainClassSimpleName" }
|
||||
var mainClassSimpleName: String by lateinitReadWriteProperty {
|
||||
pluginCoordinates?.run {
|
||||
name?.adjustToClassName() ?: id?.substringAfterLast('.')?.adjustToClassName()
|
||||
} ?: "PluginMain"
|
||||
}
|
||||
var packageName: String by lateinitReadWriteProperty { projectCoordinates.checkNotNull("projectCoordinates").groupId }
|
||||
|
||||
|
||||
var availableMiraiVersions: CompletableFuture<Set<MiraiVersion>>? = null
|
||||
val availableMiraiVersionsOrFail get() = availableMiraiVersions.checkNotNull("availableMiraiVersions")
|
||||
|
||||
fun checkValuesNotNull() {
|
||||
checkNotNull(miraiVersion) { "miraiVersion" }
|
||||
checkNotNull(pluginCoordinates) { "pluginCoordinates" }
|
||||
checkNotNull(projectCoordinates) { "projectCoordinates" }
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun create(scope: ExecutorService): MiraiProjectModel {
|
||||
return MiraiProjectModel().apply {
|
||||
availableMiraiVersions = scope.async { MiraiVersionKind.getMiraiVersionList() }
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> ExecutorService.async(block: () -> T): CompletableFuture<T> {
|
||||
val future = CompletableFuture<T>()
|
||||
submit {
|
||||
try {
|
||||
future.complete(block())
|
||||
} catch (e: Throwable) {
|
||||
future.completeExceptionally(e)
|
||||
}
|
||||
}
|
||||
return future
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val MiraiProjectModel.templateProperties: Map<String, String?>
|
||||
get() {
|
||||
val projectCoordinates = projectCoordinates!!
|
||||
val pluginCoordinates = pluginCoordinates!!
|
||||
return mapOf(
|
||||
"KOTLIN_VERSION" to KotlinVersion.CURRENT.toString(),
|
||||
"MIRAI_VERSION" to miraiVersion!!,
|
||||
"GROUP_ID" to projectCoordinates.groupId,
|
||||
"VERSION" to projectCoordinates.version,
|
||||
"USE_PROXY_REPO" to "true",
|
||||
"ARTIFACT_ID" to projectCoordinates.artifactId,
|
||||
|
||||
"PLUGIN_ID" to pluginCoordinates.id,
|
||||
"PLUGIN_NAME" to languageType.escapeString(pluginCoordinates.name),
|
||||
"PLUGIN_AUTHOR" to languageType.escapeString(pluginCoordinates.author),
|
||||
"PLUGIN_INFO" to languageType.escapeRawString(pluginCoordinates.info),
|
||||
"PLUGIN_DEPENDS_ON" to pluginCoordinates.dependsOn,
|
||||
"PLUGIN_VERSION" to projectCoordinates.version,
|
||||
|
||||
"PACKAGE_NAME" to packageName,
|
||||
"CLASS_NAME" to mainClassSimpleName,
|
||||
|
||||
"LANGUAGE_TYPE" to languageType.toString(),
|
||||
)
|
||||
}
|
||||
|
||||
fun <T : Any> T?.checkNotNull(name: String): T {
|
||||
contract {
|
||||
returns() implies (this@checkNotNull != null)
|
||||
}
|
||||
checkNotNull(this) {
|
||||
"$name is not yet initialized."
|
||||
}
|
||||
return this
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
package net.mamoe.mirai.console.intellij.creator.build
|
||||
|
||||
import com.intellij.codeInsight.actions.ReformatCodeProcessor
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import net.mamoe.mirai.console.intellij.assets.FT
|
||||
import net.mamoe.mirai.console.intellij.creator.MiraiProjectModel
|
||||
import net.mamoe.mirai.console.intellij.creator.tasks.getTemplate
|
||||
import net.mamoe.mirai.console.intellij.creator.tasks.invokeAndWait
|
||||
import net.mamoe.mirai.console.intellij.creator.tasks.runWriteActionAndWait
|
||||
import net.mamoe.mirai.console.intellij.creator.tasks.writeChild
|
||||
import net.mamoe.mirai.console.intellij.creator.templateProperties
|
||||
import org.jetbrains.kotlin.idea.core.util.toPsiFile
|
||||
import java.nio.file.Path
|
||||
|
||||
sealed class ProjectCreator(
|
||||
val module: Module,
|
||||
val root: VirtualFile,
|
||||
val model: MiraiProjectModel,
|
||||
) {
|
||||
val project get() = module.project
|
||||
|
||||
init {
|
||||
model.checkValuesNotNull()
|
||||
}
|
||||
|
||||
protected val filesChanged = mutableListOf<Path>()
|
||||
|
||||
@Synchronized
|
||||
protected fun addFileChanged(path: Path) {
|
||||
filesChanged.add(path)
|
||||
}
|
||||
|
||||
protected fun getTemplate(name: String) = project.getTemplate(name, model.templateProperties)
|
||||
|
||||
fun doFinish(indicator: ProgressIndicator) {
|
||||
indicator.text2 = "Reformatting files"
|
||||
invokeAndWait {
|
||||
for (file in filesChanged) {
|
||||
val psi = file.toFile().toPsiFile(project) ?: continue
|
||||
ReformatCodeProcessor(psi, false).run()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun createProject(
|
||||
module: Module,
|
||||
root: VirtualFile,
|
||||
model: MiraiProjectModel,
|
||||
)
|
||||
}
|
||||
|
||||
sealed class GradleProjectCreator(
|
||||
module: Module, root: VirtualFile, model: MiraiProjectModel,
|
||||
) : ProjectCreator(module, root, model) {
|
||||
override fun createProject(module: Module, root: VirtualFile, model: MiraiProjectModel) {
|
||||
runWriteActionAndWait {
|
||||
VfsUtil.createDirectoryIfMissing(root, "src/main/${model.languageType.sourceSetDirName}")
|
||||
VfsUtil.createDirectoryIfMissing(root, "src/main/resources")
|
||||
addFileChanged(root.writeChild(model.languageType.pluginMainClassFile(this)))
|
||||
addFileChanged(
|
||||
root.writeChild(
|
||||
"src/main/resources/META-INF/services/net.mamoe.mirai.console.plugin.jvm.JvmPlugin",
|
||||
model.mainClassQualifiedName
|
||||
)
|
||||
)
|
||||
addFileChanged(root.writeChild(".gitignore", getTemplate(FT.Gitignore)))
|
||||
addFileChanged(root.writeChild("gradle.properties", getTemplate(FT.GradleProperties)))
|
||||
addFileChanged(root.writeChild("src/test/kotlin/RunTerminal.kt", getTemplate(FT.RunTerminal)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class GradleKotlinProjectCreator(
|
||||
module: Module, root: VirtualFile, model: MiraiProjectModel,
|
||||
) : GradleProjectCreator(
|
||||
module, root, model,
|
||||
) {
|
||||
override fun createProject(module: Module, root: VirtualFile, model: MiraiProjectModel) {
|
||||
super.createProject(module, root, model)
|
||||
runWriteActionAndWait {
|
||||
addFileChanged(root.writeChild("build.gradle.kts", getTemplate(FT.BuildGradleKts)))
|
||||
addFileChanged(root.writeChild("settings.gradle.kts", getTemplate(FT.SettingsGradleKts)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GradleGroovyProjectCreator(
|
||||
module: Module, root: VirtualFile, model: MiraiProjectModel,
|
||||
) : GradleProjectCreator(
|
||||
module, root, model,
|
||||
) {
|
||||
override fun createProject(module: Module, root: VirtualFile, model: MiraiProjectModel) {
|
||||
super.createProject(module, root, model)
|
||||
runWriteActionAndWait {
|
||||
addFileChanged(root.writeChild("build.gradle", getTemplate(FT.BuildGradle)))
|
||||
addFileChanged(root.writeChild("settings.gradle", getTemplate(FT.SettingsGradle)))
|
||||
}
|
||||
}
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="net.mamoe.mirai.console.intellij.creator.steps.BuildSystemStep">
|
||||
<grid id="27dc6" binding="panel" layout-manager="GridLayoutManager" row-count="5" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="10" vgap="10">
|
||||
<margin top="10" left="10" bottom="10" right="10"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="589" height="400"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none" title-justification="1" title-position="3"/>
|
||||
<children>
|
||||
<component id="539d6" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="ArtifactId:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="f1b7a" class="javax.swing.JTextField" binding="artifactIdField">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="plugin"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="2c1ec" class="javax.swing.JTextField" binding="groupIdField">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="org.example"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="2e485" class="javax.swing.JTextField" binding="versionField">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="1.0-SNAPSHOT"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="6d341" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Version:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<vspacer id="3151a">
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<hspacer id="8d42b">
|
||||
<constraints>
|
||||
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="229" height="11"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<component id="33f22" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="GroupId:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="452df" class="javax.swing.JComboBox" binding="buildSystemBox">
|
||||
<constraints>
|
||||
<grid row="3" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<model/>
|
||||
<toolTipText value="Build system"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="45fb1" class="javax.swing.JComboBox" binding="languageBox">
|
||||
<constraints>
|
||||
<grid row="3" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<model/>
|
||||
<toolTipText value="Language"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="303a9" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value=""/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<buttonGroups>
|
||||
<group name="radioButtonGroup">
|
||||
<member id="80d0b"/>
|
||||
<member id="9d2d8"/>
|
||||
</group>
|
||||
</buttonGroups>
|
||||
</form>
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
package net.mamoe.mirai.console.intellij.creator.steps
|
||||
|
||||
import com.intellij.ide.util.projectWizard.ModuleWizardStep
|
||||
import net.mamoe.mirai.console.intellij.creator.MiraiProjectModel
|
||||
import net.mamoe.mirai.console.intellij.creator.ProjectCoordinates
|
||||
import net.mamoe.mirai.console.intellij.creator.tasks.PACKAGE_PATTERN
|
||||
import net.mamoe.mirai.console.intellij.diagnostics.ContextualParametersChecker.Companion.SEMANTIC_VERSIONING_PATTERN
|
||||
import javax.swing.JComboBox
|
||||
import javax.swing.JPanel
|
||||
import javax.swing.JTextField
|
||||
|
||||
/**
|
||||
* @see MiraiProjectModel.projectCoordinates
|
||||
* @see MiraiProjectModel.languageType
|
||||
* @see MiraiProjectModel.buildSystemType
|
||||
*/
|
||||
class BuildSystemStep(
|
||||
private val model: MiraiProjectModel
|
||||
) : ModuleWizardStep() {
|
||||
|
||||
private lateinit var panel: JPanel
|
||||
|
||||
@field:Validation.NotBlank("Group ID")
|
||||
@field:Validation.Pattern("Group ID", PACKAGE_PATTERN)
|
||||
private lateinit var groupIdField: JTextField
|
||||
|
||||
@field:Validation.NotBlank("Artifact ID")
|
||||
@field:Validation.Pattern("Artifact ID", PACKAGE_PATTERN)
|
||||
private lateinit var artifactIdField: JTextField
|
||||
|
||||
@field:Validation.NotBlank("Version")
|
||||
@field:Validation.Pattern("Version", SEMANTIC_VERSIONING_PATTERN)
|
||||
private lateinit var versionField: JTextField
|
||||
|
||||
private lateinit var buildSystemBox: JComboBox<BuildSystemType>
|
||||
private lateinit var languageBox: JComboBox<LanguageType>
|
||||
|
||||
override fun getComponent() = panel
|
||||
|
||||
override fun updateStep() {
|
||||
buildSystemBox.removeAllItems()
|
||||
buildSystemBox.isEnabled = true
|
||||
BuildSystemType.values().forEach { buildSystemBox.addItem(it) }
|
||||
buildSystemBox.selectedItem = BuildSystemType.DEFAULT
|
||||
buildSystemBox.toolTipText = """
|
||||
Gradle Kotlin DSL: build.gradle.kts <br/>
|
||||
Gradle Groovy DSL: build.gradle
|
||||
""".trimIndent()
|
||||
|
||||
languageBox.removeAllItems()
|
||||
languageBox.isEnabled = true
|
||||
LanguageType.values().forEach { languageBox.addItem(it) }
|
||||
languageBox.selectedItem = LanguageType.DEFAULT
|
||||
buildSystemBox.toolTipText = """
|
||||
Language for main class.
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
override fun updateDataModel() {
|
||||
model.buildSystemType = this.buildSystemBox.selectedItem as BuildSystemType
|
||||
model.languageType = this.languageBox.selectedItem as LanguageType
|
||||
model.projectCoordinates = ProjectCoordinates(
|
||||
groupId = groupIdField.text,
|
||||
artifactId = artifactIdField.text,
|
||||
version = versionField.text
|
||||
)
|
||||
}
|
||||
|
||||
override fun validate() = Validation.doValidation(this)
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.intellij.creator.steps
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import net.mamoe.mirai.console.intellij.creator.MiraiProjectModel
|
||||
import net.mamoe.mirai.console.intellij.creator.build.GradleGroovyProjectCreator
|
||||
import net.mamoe.mirai.console.intellij.creator.build.GradleKotlinProjectCreator
|
||||
import net.mamoe.mirai.console.intellij.creator.build.ProjectCreator
|
||||
|
||||
enum class BuildSystemType {
|
||||
GradleKt {
|
||||
override fun createBuildSystem(module: Module, root: VirtualFile, model: MiraiProjectModel): ProjectCreator =
|
||||
GradleKotlinProjectCreator(module, root, model)
|
||||
|
||||
override fun toString(): String = "Gradle Kotlin DSL"
|
||||
},
|
||||
GradleGroovy {
|
||||
override fun createBuildSystem(module: Module, root: VirtualFile, model: MiraiProjectModel): ProjectCreator =
|
||||
GradleGroovyProjectCreator(module, root, model)
|
||||
|
||||
override fun toString(): String = "Gradle Groovy DSL"
|
||||
}, ;
|
||||
|
||||
abstract fun createBuildSystem(module: Module, root: VirtualFile, model: MiraiProjectModel): ProjectCreator
|
||||
|
||||
companion object {
|
||||
val DEFAULT = GradleKt
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="net.mamoe.mirai.console.intellij.creator.steps.OptionsStep">
|
||||
<grid id="27dc6" binding="panel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
</form>
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
package net.mamoe.mirai.console.intellij.creator.steps
|
||||
|
||||
import com.intellij.ide.util.projectWizard.ModuleWizardStep
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.JPanel
|
||||
|
||||
class OptionsStep : ModuleWizardStep() {
|
||||
private lateinit var panel: JPanel
|
||||
|
||||
override fun getComponent(): JComponent {
|
||||
return panel
|
||||
}
|
||||
|
||||
override fun updateDataModel() {
|
||||
}
|
||||
}
|
@ -1,215 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="net.mamoe.mirai.console.intellij.creator.steps.PluginCoordinatesStep">
|
||||
<grid id="27dc6" binding="panel" layout-manager="GridLayoutManager" row-count="11" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="10" vgap="10">
|
||||
<margin top="10" left="10" bottom="10" right="10"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="531" height="541"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none" title-justification="1" title-position="3"/>
|
||||
<children>
|
||||
<vspacer id="3151a">
|
||||
<constraints>
|
||||
<grid row="10" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="303a9" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="10" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value=""/>
|
||||
<visible value="false"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="539d6" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="10" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value=""/>
|
||||
<toolTipText value=""/>
|
||||
<visible value="false"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="33f22" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="8" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Info:"/>
|
||||
<toolTipText value="描述"/>
|
||||
</properties>
|
||||
</component>
|
||||
<vspacer id="b4a73">
|
||||
<constraints>
|
||||
<grid row="9" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="980c2" class="javax.swing.JTextArea" binding="infoArea">
|
||||
<constraints>
|
||||
<grid row="8" column="1" row-span="1" col-span="2" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="119"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<dragEnabled value="true"/>
|
||||
<text value=""/>
|
||||
<toolTipText value="描述, 可选"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="3ca24" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Author:"/>
|
||||
<toolTipText value="作者"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="45051" class="javax.swing.JTextField" binding="authorField">
|
||||
<constraints>
|
||||
<grid row="6" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value=""/>
|
||||
<toolTipText value="作者名称, 可选"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="c6d49" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Name:"/>
|
||||
<toolTipText value="显示名称"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="27fb6" class="javax.swing.JTextField" binding="nameField">
|
||||
<constraints>
|
||||
<grid row="5" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value=""/>
|
||||
<toolTipText value="显示名称, 可选"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="28e8e" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Depends on:"/>
|
||||
<toolTipText value="依赖的插件列表"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="44e5c" class="javax.swing.JTextField" binding="dependsOnField">
|
||||
<constraints>
|
||||
<grid row="7" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<enabled value="false"/>
|
||||
<text value=""/>
|
||||
<toolTipText value="依赖的插件列表, 还不支持编辑, 请在创建项目后修改"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="53007" class="javax.swing.JSeparator">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="45fb1" class="javax.swing.JComboBox" binding="miraiVersionBox">
|
||||
<constraints>
|
||||
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<editable value="true"/>
|
||||
<enabled value="false"/>
|
||||
<model>
|
||||
<item value="Loading..."/>
|
||||
</model>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="6d341" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<opaque value="true"/>
|
||||
<text value="Mirai version:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="452df" class="javax.swing.JComboBox" binding="miraiVersionKindBox">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<enabled value="false"/>
|
||||
<model>
|
||||
<item value="Stable"/>
|
||||
<item value="Prerelease"/>
|
||||
</model>
|
||||
<toolTipText value="Mirai 版本类型 <br/> Stable: 稳定 Prerelease: -M 和 -RC 测试版" noi18n="true"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="6ddd1" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="*ID:"/>
|
||||
<toolTipText value=""/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="a76eb" class="javax.swing.JTextField" binding="idField">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value=""/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="9ee7e" class="javax.swing.JTextField" binding="mainClassField">
|
||||
<constraints>
|
||||
<grid row="3" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value=""/>
|
||||
<toolTipText value="依赖的插件列表, 可选"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="f4c2b" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="*Main class:"/>
|
||||
<toolTipText value="依赖的插件列表"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="f7d3f" class="javax.swing.JSeparator">
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<buttonGroups>
|
||||
<group name="radioButtonGroup">
|
||||
<member id="80d0b"/>
|
||||
<member id="9d2d8"/>
|
||||
</group>
|
||||
</buttonGroups>
|
||||
</form>
|
@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
package net.mamoe.mirai.console.intellij.creator.steps
|
||||
|
||||
import com.intellij.ide.util.projectWizard.ModuleWizardStep
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.vcs.log.submitSafe
|
||||
import net.mamoe.mirai.console.compiler.common.CheckerConstants.PLUGIN_ID_PATTERN
|
||||
import net.mamoe.mirai.console.intellij.creator.MiraiProjectModel
|
||||
import net.mamoe.mirai.console.intellij.creator.MiraiVersionKind
|
||||
import net.mamoe.mirai.console.intellij.creator.PluginCoordinates
|
||||
import net.mamoe.mirai.console.intellij.creator.checkNotNull
|
||||
import net.mamoe.mirai.console.intellij.creator.steps.Validation.NotBlank
|
||||
import net.mamoe.mirai.console.intellij.creator.steps.Validation.Pattern
|
||||
import net.mamoe.mirai.console.intellij.creator.tasks.QUALIFIED_CLASS_NAME_PATTERN
|
||||
import net.mamoe.mirai.console.intellij.creator.tasks.adjustToClassName
|
||||
import net.mamoe.mirai.console.intellij.diagnostics.ContextualParametersChecker
|
||||
import java.awt.event.ItemEvent
|
||||
import java.awt.event.ItemListener
|
||||
import java.util.concurrent.ExecutorService
|
||||
import javax.swing.*
|
||||
|
||||
class PluginCoordinatesStep(
|
||||
private val model: MiraiProjectModel,
|
||||
private val scope: ExecutorService,
|
||||
) : ModuleWizardStep() {
|
||||
|
||||
private lateinit var panel: JPanel
|
||||
|
||||
@field:NotBlank("ID")
|
||||
@field:Pattern("ID", PLUGIN_ID_PATTERN)
|
||||
private lateinit var idField: JTextField
|
||||
|
||||
@field:NotBlank("Main class")
|
||||
@field:Pattern("Main class", QUALIFIED_CLASS_NAME_PATTERN)
|
||||
private lateinit var mainClassField: JTextField
|
||||
private lateinit var nameField: JTextField
|
||||
private lateinit var authorField: JTextField
|
||||
private lateinit var dependsOnField: JTextField
|
||||
private lateinit var infoArea: JTextArea
|
||||
private lateinit var miraiVersionKindBox: JComboBox<MiraiVersionKind>
|
||||
|
||||
@field:NotBlank("Mirai version")
|
||||
@field:Pattern("Mirai version", ContextualParametersChecker.SEMANTIC_VERSIONING_PATTERN)
|
||||
private lateinit var miraiVersionBox: JComboBox<String>
|
||||
|
||||
override fun getComponent() = panel
|
||||
|
||||
private val versionKindChangeListener: ItemListener = ItemListener { event ->
|
||||
if (event.stateChange != ItemEvent.SELECTED) return@ItemListener
|
||||
|
||||
updateVersionItemsAsync()
|
||||
}
|
||||
|
||||
override fun getPreferredFocusedComponent(): JComponent = idField
|
||||
|
||||
override fun updateStep() {
|
||||
miraiVersionKindBox.removeAllItems()
|
||||
miraiVersionKindBox.isEnabled = true
|
||||
MiraiVersionKind.values().forEach { miraiVersionKindBox.addItem(it) }
|
||||
miraiVersionKindBox.selectedItem = MiraiVersionKind.DEFAULT
|
||||
miraiVersionKindBox.addItemListener(versionKindChangeListener) // when selected, change versions
|
||||
|
||||
miraiVersionBox.removeAllItems()
|
||||
miraiVersionBox.addItem(VERSION_LOADING_PLACEHOLDER)
|
||||
miraiVersionBox.selectedItem = VERSION_LOADING_PLACEHOLDER
|
||||
|
||||
model.availableMiraiVersionsOrFail.whenComplete { _, _ ->
|
||||
updateVersionItemsAsync()
|
||||
}
|
||||
|
||||
if (idField.text.isNullOrEmpty()) {
|
||||
model.projectCoordinates.checkNotNull("projectCoordinates").run {
|
||||
idField.text = "$groupId.$artifactId"
|
||||
}
|
||||
}
|
||||
|
||||
if (mainClassField.text.isNullOrEmpty()) {
|
||||
model.projectCoordinates.checkNotNull("projectCoordinates").run {
|
||||
mainClassField.text = "$groupId.${artifactId.adjustToClassName()}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateVersionItemsAsync() {
|
||||
scope.submitSafe(LOG) {
|
||||
if (!model.availableMiraiVersionsOrFail.isDone) return@submitSafe
|
||||
miraiVersionBox.removeAllItems()
|
||||
val expectingKind = miraiVersionKindBox.selectedItem as? MiraiVersionKind ?: MiraiVersionKind.DEFAULT
|
||||
kotlin.runCatching { model.availableMiraiVersionsOrFail.join() }
|
||||
.fold(
|
||||
onSuccess = { versions ->
|
||||
versions
|
||||
.filter { v -> expectingKind.isThatKind(v) }
|
||||
.forEach { v -> miraiVersionBox.addItem(v) }
|
||||
},
|
||||
onFailure = { e ->
|
||||
Validation.popup(
|
||||
"Failed to download version list, please select a version by yourself. \nCause: ${e.cause ?: e}",
|
||||
miraiVersionBox
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
miraiVersionBox.isEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateDataModel() {
|
||||
model.pluginCoordinates = PluginCoordinates(
|
||||
id = idField.text.trim(),
|
||||
author = authorField.text,
|
||||
name = nameField.text?.trim(),
|
||||
info = infoArea.text?.trim(),
|
||||
dependsOn = dependsOnField.text?.trim(),
|
||||
)
|
||||
model.miraiVersion = miraiVersionBox.selectedItem?.toString()?.trim() ?: "+"
|
||||
model.packageName = mainClassField.text.substringBeforeLast('.')
|
||||
model.mainClassSimpleName = mainClassField.text.substringAfterLast('.')
|
||||
model.mainClassQualifiedName = mainClassField.text
|
||||
}
|
||||
|
||||
override fun validate(): Boolean {
|
||||
if (miraiVersionBox.selectedItem?.toString() == VERSION_LOADING_PLACEHOLDER) {
|
||||
Validation.popup("请等待获取版本号", miraiVersionBox)
|
||||
return false
|
||||
}
|
||||
if (!Validation.doValidation(this)) return false
|
||||
if (!mainClassField.text.contains('.')) {
|
||||
Validation.popup("Main class 需要包含包名", mainClassField)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val VERSION_LOADING_PLACEHOLDER = "Loading..."
|
||||
private val LOG = Logger.getInstance(PluginCoordinatesStep::class.java)
|
||||
}
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
package net.mamoe.mirai.console.intellij.creator.steps
|
||||
|
||||
import com.intellij.ide.util.projectWizard.ModuleWizardStep
|
||||
import com.intellij.openapi.ui.MessageType
|
||||
import com.intellij.openapi.ui.popup.Balloon
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory
|
||||
import com.intellij.ui.awt.RelativePoint
|
||||
import net.mamoe.mirai.console.compiler.common.cast
|
||||
import org.intellij.lang.annotations.Language
|
||||
import java.lang.reflect.Field
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.text.JTextComponent
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.createInstance
|
||||
|
||||
|
||||
class Validation {
|
||||
|
||||
annotation class WithValidator(val clazz: KClass<out Validator<WithValidator>>) {
|
||||
companion object {
|
||||
init {
|
||||
registerValidator<WithValidator> { annotation, component ->
|
||||
val instance = annotation.clazz.objectInstance ?: annotation.clazz.createInstance()
|
||||
instance.validate(annotation, component)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
annotation class NotBlank(val tipName: String) {
|
||||
companion object {
|
||||
init {
|
||||
registerValidator<NotBlank> { annotation, component ->
|
||||
if (component.text.isNullOrBlank()) {
|
||||
report("请填写 ${annotation.tipName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
annotation class Pattern(val tipName: String, @Language("RegExp") val value: String) {
|
||||
companion object {
|
||||
init {
|
||||
registerValidator<Pattern> { annotation, component ->
|
||||
if (component.text?.matches(Regex(annotation.value)) != true) {
|
||||
report("请正确填写 ${annotation.tipName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun interface Validator<in A : Annotation> {
|
||||
@Throws(ValidationException::class)
|
||||
fun ValidationContext.validate(annotation: A, component: JTextComponent)
|
||||
|
||||
@Throws(ValidationException::class)
|
||||
fun validate(annotation: A, component: JTextComponent) {
|
||||
ValidationContext.run { validate(annotation, component) }
|
||||
}
|
||||
|
||||
object ValidationContext {
|
||||
fun report(message: String): Nothing = throw ValidationException(message)
|
||||
}
|
||||
}
|
||||
|
||||
class ValidationException(message: String) : Exception(message)
|
||||
|
||||
companion object {
|
||||
private data class RegisteredValidator<A : Annotation>(val type: KClass<A>, val validator: Validator<A>)
|
||||
|
||||
private val validators: MutableCollection<RegisteredValidator<*>> = ConcurrentLinkedQueue()
|
||||
|
||||
private inline fun <reified A : Annotation> registerValidator(validator: Validator<A>) {
|
||||
validators.add(RegisteredValidator(A::class, validator))
|
||||
}
|
||||
|
||||
fun popup(message: String, component: JComponent) {
|
||||
JBPopupFactory.getInstance()
|
||||
.createHtmlTextBalloonBuilder(message, MessageType.ERROR, null)
|
||||
.setFadeoutTime(2000)
|
||||
.createBalloon()
|
||||
.show(RelativePoint.getSouthWestOf(component), Balloon.Position.below)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return `true` if no error
|
||||
*/
|
||||
fun doValidation(step: ModuleWizardStep): Boolean {
|
||||
fun validateProperty(field: Field): Boolean {
|
||||
field.isAccessible = true
|
||||
val annotationsToValidate =
|
||||
validators.associateBy { (type: KClass<out Annotation>) ->
|
||||
field.annotations.find { it::class == type }
|
||||
}
|
||||
|
||||
for ((annotation, validator) in annotationsToValidate) {
|
||||
if (annotation == null) continue
|
||||
val component = field.get(step) as JTextComponent
|
||||
try {
|
||||
validator.validator.cast<Validator<Annotation>>().validate(annotation, component)
|
||||
} catch (e: ValidationException) {
|
||||
popup(e.message ?: e.toString(), component)
|
||||
return false // report one error only
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
var result = true
|
||||
for (prop in step::class.java.declaredFields) {
|
||||
if (!validateProperty(prop)) result = false
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
package net.mamoe.mirai.console.intellij.creator.tasks
|
||||
|
||||
import com.intellij.ide.ui.UISettings
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.Task
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
import com.intellij.openapi.wm.WindowManager
|
||||
import com.intellij.openapi.wm.ex.StatusBarEx
|
||||
import net.mamoe.mirai.console.intellij.creator.MiraiProjectModel
|
||||
import org.jetbrains.kotlin.idea.util.application.invokeLater
|
||||
import org.jetbrains.plugins.gradle.service.project.open.linkAndRefreshGradleProject
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
|
||||
class CreateProjectTask(
|
||||
private val root: Path,
|
||||
private val module: Module,
|
||||
private val model: MiraiProjectModel,
|
||||
) : Task.Backgroundable(module.project, "Creating project", false) {
|
||||
override fun shouldStartInBackground() = false
|
||||
|
||||
override fun run(indicator: ProgressIndicator) {
|
||||
if (module.isDisposed || project.isDisposed) return
|
||||
|
||||
Files.createDirectories(root)
|
||||
|
||||
invokeAndWait {
|
||||
VfsUtil.markDirtyAndRefresh(false, true, true, root.vf)
|
||||
}
|
||||
|
||||
val build = model.buildSystemType.createBuildSystem(module, root.vf, model)
|
||||
|
||||
build.createProject(module, root.vf, model)
|
||||
|
||||
invokeLater {
|
||||
VfsUtil.markDirtyAndRefresh(false, true, true, root.vf)
|
||||
}
|
||||
|
||||
invokeLater {
|
||||
linkAndRefreshGradleProject(root.toAbsolutePath().toString(), project)
|
||||
showProgress(project)
|
||||
}
|
||||
|
||||
build.doFinish(indicator)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun showProgress(project: Project) {
|
||||
if (!UISettings.instance.showStatusBar || UISettings.instance.presentationMode) {
|
||||
return
|
||||
}
|
||||
|
||||
val statusBar = WindowManager.getInstance().getStatusBar(project) as? StatusBarEx ?: return
|
||||
statusBar.isProcessWindowOpen = true
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
@ -22,12 +22,12 @@ import net.mamoe.mirai.console.intellij.diagnostics.fix.ConfigurePluginMainServi
|
||||
import net.mamoe.mirai.console.intellij.resolve.allSuperNames
|
||||
import net.mamoe.mirai.console.intellij.resolve.hasAnnotation
|
||||
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
|
||||
import org.jetbrains.kotlin.idea.debugger.readAction
|
||||
import org.jetbrains.kotlin.idea.util.*
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.idea.util.module
|
||||
import org.jetbrains.kotlin.idea.util.rootManager
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
import org.jetbrains.kotlin.psi.classOrObjectVisitor
|
||||
import java.util.*
|
||||
|
||||
/*
|
||||
private val bundle by lazy {
|
||||
@ -107,8 +107,9 @@ class PluginMainServiceNotConfiguredInspection : AbstractKotlinInspection() {
|
||||
}
|
||||
}
|
||||
return@runWithCancellationCheck services.any { serviceFile ->
|
||||
serviceFile.readAction { f ->
|
||||
f.inputStream.bufferedReader().use { reader -> reader.lineSequence().any { it == fqName } }
|
||||
runReadAction {
|
||||
serviceFile.inputStream.bufferedReader()
|
||||
.use { reader -> reader.lineSequence().any { it == fqName } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
@ -16,11 +16,11 @@ import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.*
|
||||
import net.mamoe.mirai.console.intellij.resolve.*
|
||||
import org.jetbrains.kotlin.idea.base.utils.fqname.getKotlinFqName
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
||||
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
|
||||
import org.jetbrains.kotlin.idea.inspections.KotlinUniversalQuickFix
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinCrossLanguageQuickFixAction
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
||||
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@ -28,7 +28,7 @@ import org.jetbrains.kotlin.nj2k.postProcessing.resolve
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.referenceExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||
import org.jetbrains.kotlin.resolve.calls.util.getCalleeExpressionIfAny
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import kotlin.contracts.contract
|
||||
|
||||
|
@ -8,23 +8,14 @@
|
||||
*/
|
||||
|
||||
|
||||
package net.mamoe.mirai.console.intellij.creator.tasks
|
||||
package net.mamoe.mirai.console.intellij.diagnostics
|
||||
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.util.io.writeChild
|
||||
import net.mamoe.mirai.console.intellij.creator.steps.NamedFile
|
||||
import org.intellij.lang.annotations.Language
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
val Path.vfOrNull: VirtualFile?
|
||||
get() = LocalFileSystem.getInstance().refreshAndFindFileByPath(this.toAbsolutePath().toString())
|
||||
@ -42,20 +33,6 @@ fun VirtualFile.resolve(relative: String): VirtualFile? = VfsUtil.findRelativeFi
|
||||
*relative.replace('\\', '/').split('/').toTypedArray()
|
||||
)
|
||||
|
||||
fun <T> invokeAndWait(modalityState: ModalityState? = null, runnable: () -> T): T {
|
||||
val app = ApplicationManager.getApplication()
|
||||
if (app.isDispatchThread) return runnable()
|
||||
return computeDelegated {
|
||||
app.invokeAndWait({ it(runnable()) }, modalityState ?: ModalityState.defaultModalityState())
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> runWriteActionAndWait(modalityState: ModalityState? = null, runnable: () -> T) {
|
||||
invokeAndWait(modalityState) {
|
||||
runWriteAction(runnable)
|
||||
}
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal inline fun <T> computeDelegated(executor: (setter: (T) -> Unit) -> Unit): T {
|
||||
var resultRef: T? = null
|
||||
@ -64,29 +41,6 @@ internal inline fun <T> computeDelegated(executor: (setter: (T) -> Unit) -> Unit
|
||||
return resultRef as T
|
||||
}
|
||||
|
||||
fun Project.getTemplate(
|
||||
templateName: String,
|
||||
properties: Map<String, String?>? = null
|
||||
): String {
|
||||
val manager = FileTemplateManager.getInstance(this)
|
||||
val template = manager.getJ2eeTemplate(templateName)
|
||||
|
||||
val allProperties = manager.defaultProperties
|
||||
properties?.let { prop -> allProperties.putAll(prop.mapValues { it.value.orEmpty() }) }
|
||||
|
||||
return template.getText(allProperties)
|
||||
}
|
||||
|
||||
fun Project.getTemplate(
|
||||
templateName: String,
|
||||
vararg properties: Pair<String, String?>
|
||||
): String = getTemplate(templateName, properties.toMap())
|
||||
|
||||
|
||||
internal fun VirtualFile.writeChild(pluginMainClassFile: NamedFile): Path {
|
||||
return writeChild(pluginMainClassFile.path, pluginMainClassFile.content)
|
||||
}
|
||||
|
||||
internal fun VirtualFile.writeChild(path: String, content: String): Path {
|
||||
return toNioPath().writeChild(path, content)
|
||||
}
|
||||
@ -136,22 +90,4 @@ fun String.adjustToClassName(): String? {
|
||||
if (result.isValidSimpleClassName()) return result
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@Suppress("RedundantNullableReturnType")
|
||||
private val UNINITIALIZED: Any? = Any()
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T, R> lateinitReadWriteProperty(initializer: () -> R) = object : ReadWriteProperty<T, R> {
|
||||
private var field = AtomicReference(UNINITIALIZED)
|
||||
override fun setValue(thisRef: T, property: KProperty<*>, value: R) {
|
||||
field.set(value)
|
||||
}
|
||||
|
||||
override tailrec fun getValue(thisRef: T, property: KProperty<*>): R {
|
||||
val v = field.get()
|
||||
if (v !== UNINITIALIZED) return v as R
|
||||
field.compareAndSet(UNINITIALIZED, initializer())
|
||||
return getValue(thisRef, property)
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
@ -27,7 +27,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForReceiver
|
||||
import org.jetbrains.kotlin.psi.psiUtil.referenceExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||
import org.jetbrains.kotlin.resolve.calls.util.getCalleeExpressionIfAny
|
||||
|
||||
/*
|
||||
private val bundle by lazy {
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.intellij.diagnostics
|
||||
@ -15,7 +15,7 @@ import net.mamoe.mirai.console.compiler.common.resolve.READ_ONLY_PLUGIN_DATA_FQ_
|
||||
import net.mamoe.mirai.console.intellij.resolve.getResolvedCall
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||
import org.jetbrains.kotlin.idea.base.utils.fqname.getKotlinFqName
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
@ -16,8 +16,8 @@ import com.intellij.openapi.project.rootManager
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import net.mamoe.mirai.console.intellij.creator.tasks.readChildText
|
||||
import net.mamoe.mirai.console.intellij.creator.tasks.writeChild
|
||||
import net.mamoe.mirai.console.intellij.diagnostics.readChildText
|
||||
import net.mamoe.mirai.console.intellij.diagnostics.writeChild
|
||||
import org.jetbrains.kotlin.idea.core.isAndroidModule
|
||||
import org.jetbrains.kotlin.idea.inspections.KotlinUniversalQuickFix
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinCrossLanguageQuickFixAction
|
||||
|
@ -14,10 +14,10 @@ import com.intellij.psi.PsiModifier
|
||||
import net.mamoe.mirai.console.intellij.diagnostics.resolveReferencedType
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.idea.base.utils.fqname.getKotlinFqName
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.getReturnTypeReference
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.fqName
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.nj2k.postProcessing.type
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
|
@ -1,22 +1,23 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.intellij.resolve
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.*
|
||||
import net.mamoe.mirai.console.compiler.common.resolve.*
|
||||
import net.mamoe.mirai.console.compiler.common.resolve.COMPOSITE_COMMAND_SUB_COMMAND_FQ_NAME
|
||||
import net.mamoe.mirai.console.compiler.common.resolve.SIMPLE_COMMAND_HANDLER_COMMAND_FQ_NAME
|
||||
import net.mamoe.mirai.console.compiler.common.resolve.findParent
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.base.utils.fqname.getKotlinFqName
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.fqName
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||
import org.jetbrains.kotlin.idea.references.resolveToDescriptors
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
@ -26,10 +27,9 @@ import org.jetbrains.kotlin.nj2k.postProcessing.resolve
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.referenceExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.util.getCall
|
||||
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.intellij.wizard
|
||||
|
||||
enum class BuildSystemType {
|
||||
GradleKt {
|
||||
override fun createBuildSystem(model: MiraiProjectModel): ProjectCreator =
|
||||
GradleKotlinProjectCreator(model)
|
||||
|
||||
override fun toString(): String = "Gradle Kotlin DSL"
|
||||
},
|
||||
GradleGroovy {
|
||||
override fun createBuildSystem(model: MiraiProjectModel): ProjectCreator =
|
||||
GradleGroovyProjectCreator(model)
|
||||
|
||||
override fun toString(): String = "Gradle Groovy DSL"
|
||||
}, ;
|
||||
|
||||
abstract fun createBuildSystem(model: MiraiProjectModel): ProjectCreator
|
||||
}
|
@ -1,22 +1,20 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.intellij.creator.steps
|
||||
package net.mamoe.mirai.console.intellij.wizard
|
||||
|
||||
import com.intellij.ide.fileTemplates.FileTemplate
|
||||
import net.mamoe.mirai.console.intellij.assets.FT
|
||||
import net.mamoe.mirai.console.intellij.creator.build.ProjectCreator
|
||||
import net.mamoe.mirai.console.intellij.creator.tasks.getTemplate
|
||||
import net.mamoe.mirai.console.intellij.creator.templateProperties
|
||||
|
||||
data class NamedFile(
|
||||
val path: String,
|
||||
val content: String
|
||||
val template: FileTemplate
|
||||
)
|
||||
|
||||
interface ILanguageType {
|
||||
@ -37,7 +35,6 @@ sealed class LanguageType : ILanguageType {
|
||||
abstract fun <T : String?> escapeRawString(string: T): T
|
||||
|
||||
companion object {
|
||||
val DEFAULT = Kotlin
|
||||
fun values() = arrayOf(Kotlin, Java)
|
||||
}
|
||||
|
||||
@ -47,7 +44,7 @@ sealed class LanguageType : ILanguageType {
|
||||
override fun pluginMainClassFile(creator: ProjectCreator): NamedFile = creator.model.run {
|
||||
return NamedFile(
|
||||
path = "src/main/kotlin/$mainClassSimpleName.kt",
|
||||
content = creator.project.getTemplate(FT.PluginMainKt, templateProperties)
|
||||
template = creator.getTemplate(FT.PluginMainKt)
|
||||
)
|
||||
}
|
||||
|
||||
@ -64,7 +61,7 @@ sealed class LanguageType : ILanguageType {
|
||||
override fun pluginMainClassFile(creator: ProjectCreator): NamedFile = creator.model.run {
|
||||
return NamedFile(
|
||||
path = "src/main/java/${packageName.replace('.', '/')}/$mainClassSimpleName.java",
|
||||
content = creator.project.getTemplate(FT.PluginMainJava, templateProperties)
|
||||
template = creator.getTemplate(FT.PluginMainJava)
|
||||
)
|
||||
}
|
||||
|
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
package net.mamoe.mirai.console.intellij.wizard
|
||||
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager
|
||||
import com.intellij.ide.starters.local.*
|
||||
import com.intellij.ide.starters.local.wizard.StarterInitialStep
|
||||
import com.intellij.ide.starters.shared.*
|
||||
import com.intellij.ide.util.projectWizard.ModuleWizardStep
|
||||
import com.intellij.ide.util.projectWizard.WizardContext
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
import com.intellij.openapi.roots.ui.configuration.ModulesProvider
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.pom.java.LanguageLevel
|
||||
import com.intellij.util.lang.JavaVersion
|
||||
import net.mamoe.mirai.console.intellij.assets.FT
|
||||
import net.mamoe.mirai.console.intellij.assets.Icons
|
||||
|
||||
class MiraiModuleBuilder : StarterModuleBuilder() {
|
||||
companion object {
|
||||
val MIRAI_PROJECT_MODEL_KEY = Key.create<MiraiProjectModel>("mirai.project.model")
|
||||
|
||||
val GRADLE_GROOVY_PROJECT: StarterProjectType = StarterProjectType("gradleGroovy", "Gradle Groovy DSL")
|
||||
val GRADLE_KTS_PROJECT: StarterProjectType = StarterProjectType("gradleKts", "Gradle Kotlin DSL")
|
||||
}
|
||||
|
||||
override fun getBuilderId() = "MiraiModuleBuilder"
|
||||
override fun getPresentableName() = MiraiProjectWizardBundle.message("module.presentation.name")
|
||||
override fun getWeight() = KOTLIN_WEIGHT - 2
|
||||
override fun getNodeIcon() = Icons.MainIcon
|
||||
override fun getDescription(): String = MiraiProjectWizardBundle.message("module.description")
|
||||
|
||||
override fun getProjectTypes(): List<StarterProjectType> = listOf(GRADLE_GROOVY_PROJECT, GRADLE_KTS_PROJECT)
|
||||
override fun getTestFrameworks(): List<StarterTestRunner> = listOf(JUNIT_TEST_RUNNER)
|
||||
override fun getMinJavaVersion(): JavaVersion = LanguageLevel.JDK_1_8.toJavaVersion()
|
||||
|
||||
override fun getStarterPack(): StarterPack {
|
||||
return StarterPack(
|
||||
"mirai", listOf(
|
||||
Starter("mirai", "Mirai Console", getDependencyConfig("/starters/compose.pom"), emptyList())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun getLanguages(): List<StarterLanguage> = listOf(JAVA_STARTER_LANGUAGE, KOTLIN_STARTER_LANGUAGE)
|
||||
|
||||
|
||||
override fun createWizardSteps(
|
||||
wizardContext: WizardContext,
|
||||
modulesProvider: ModulesProvider
|
||||
): Array<ModuleWizardStep> = emptyArray()
|
||||
|
||||
override fun createOptionsStep(contextProvider: StarterContextProvider): StarterInitialStep {
|
||||
return MiraiProjectWizardInitialStep(contextProvider)
|
||||
}
|
||||
|
||||
override fun setupModule(module: Module) {
|
||||
// manually set, we do not show the second page with libraries
|
||||
starterContext.starter = starterContext.starterPack.starters.first()
|
||||
starterContext.starterDependencyConfig = loadDependencyConfig()[starterContext.starter?.id]
|
||||
|
||||
super.setupModule(module)
|
||||
}
|
||||
|
||||
override fun getTemplateProperties(): Map<String, Any> {
|
||||
val model = starterContext.getUserData(MIRAI_PROJECT_MODEL_KEY)!!
|
||||
model.run {
|
||||
val projectCoordinates = projectCoordinates
|
||||
val pluginCoordinates = pluginCoordinates
|
||||
return mapOf<String, Any>(
|
||||
"KOTLIN_VERSION" to KotlinVersion.CURRENT.toString(),
|
||||
"MIRAI_VERSION" to miraiVersion,
|
||||
"GROUP_ID" to projectCoordinates.groupId,
|
||||
"VERSION" to projectCoordinates.version,
|
||||
"PROJECT_NAME" to starterContext,
|
||||
"USE_PROXY_REPO" to "true",
|
||||
"ARTIFACT_ID" to projectCoordinates.artifactId,
|
||||
"MODULE_NAME" to projectCoordinates.moduleName,
|
||||
|
||||
"PLUGIN_ID" to pluginCoordinates.id,
|
||||
"PLUGIN_NAME" to languageType.escapeString(pluginCoordinates.name),
|
||||
"PLUGIN_AUTHOR" to languageType.escapeString(pluginCoordinates.author),
|
||||
"PLUGIN_INFO" to languageType.escapeRawString(pluginCoordinates.info),
|
||||
"PLUGIN_DEPENDS_ON" to pluginCoordinates.dependsOn,
|
||||
"PLUGIN_VERSION" to projectCoordinates.version,
|
||||
|
||||
"PACKAGE_NAME" to packageName,
|
||||
"CLASS_NAME" to mainClassSimpleName,
|
||||
|
||||
"LANGUAGE_TYPE" to languageType.toString(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getAssets(starter: Starter): List<GeneratorAsset> {
|
||||
val ftManager = FileTemplateManager.getInstance(ProjectManager.getInstance().defaultProject)
|
||||
val assets = mutableListOf<GeneratorAsset>()
|
||||
|
||||
val model = starterContext.getUserData(MIRAI_PROJECT_MODEL_KEY)!!
|
||||
|
||||
val standardAssetsProvider = StandardAssetsProvider()
|
||||
assets.addAll(standardAssetsProvider.getGradlewAssets())
|
||||
|
||||
model.buildSystemType.createBuildSystem(model)
|
||||
.collectAssets { assets.add(it) }
|
||||
|
||||
assets.add(
|
||||
GeneratorTemplateFile(
|
||||
"src/main/resources/META-INF/services/net.mamoe.mirai.console.plugin.jvm.JvmPlugin",
|
||||
ftManager.getCodeTemplate(FT.PluginMainService)
|
||||
)
|
||||
)
|
||||
|
||||
assets.add(GeneratorEmptyDirectory("debug-sandbox"))
|
||||
assets.add(GeneratorEmptyDirectory("debug-sandbox/plugins"))
|
||||
assets.add(GeneratorEmptyDirectory("debug-sandbox/data"))
|
||||
assets.add(GeneratorEmptyDirectory("debug-sandbox/config"))
|
||||
assets.add(
|
||||
GeneratorTemplateFile(
|
||||
"debug-sandbox/account.properties",
|
||||
ftManager.getCodeTemplate(FT.AccountProperties)
|
||||
)
|
||||
)
|
||||
|
||||
assets.add(GeneratorTemplateFile(".run/RunTerminal.run.xml", ftManager.getCodeTemplate(FT.RunTerminalRun)))
|
||||
|
||||
return assets
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
package net.mamoe.mirai.console.intellij.creator
|
||||
package net.mamoe.mirai.console.intellij.wizard
|
||||
|
||||
import com.intellij.openapi.module.JavaModuleType
|
||||
import com.intellij.openapi.module.ModuleType
|
||||
import com.intellij.openapi.module.ModuleTypeManager
|
||||
import net.mamoe.mirai.console.intellij.assets.Icons
|
||||
|
||||
class MiraiModuleType : JavaModuleType() {
|
||||
class MiraiModuleType : ModuleType<MiraiModuleBuilder>("MIRAI_CONSOLE_PLUGIN_MODULE") {
|
||||
override fun createModuleBuilder() = MiraiModuleBuilder()
|
||||
override fun getIcon() = Icons.MainIcon
|
||||
override fun getNodeIcon(isOpened: Boolean) = Icons.MainIcon
|
||||
@ -23,7 +23,7 @@ class MiraiModuleType : JavaModuleType() {
|
||||
"Modules used for developing plugins for <b>Mirai Console</b>"
|
||||
|
||||
companion object {
|
||||
private const val ID = "MIRAI_MODULE_TYPE"
|
||||
private const val ID = "MIRAI_CONSOLE_PLUGIN_MODULE"
|
||||
const val NAME = "Mirai"
|
||||
|
||||
val instance: MiraiModuleType
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
package net.mamoe.mirai.console.intellij.wizard
|
||||
|
||||
import net.mamoe.mirai.console.intellij.diagnostics.adjustToClassName
|
||||
import kotlin.contracts.contract
|
||||
|
||||
data class ProjectCoordinates(
|
||||
val groupId: String, // already checked by pattern
|
||||
val artifactId: String,
|
||||
val version: String,
|
||||
val moduleName: String
|
||||
) {
|
||||
val packageName: String get() = groupId
|
||||
}
|
||||
|
||||
data class PluginCoordinates(
|
||||
val id: String,
|
||||
val name: String,
|
||||
val author: String,
|
||||
val info: String,
|
||||
val dependsOn: String,
|
||||
)
|
||||
|
||||
class MiraiProjectModel(
|
||||
val projectCoordinates: ProjectCoordinates,
|
||||
val pluginCoordinates: PluginCoordinates,
|
||||
val miraiVersion: String,
|
||||
|
||||
val buildSystemType: BuildSystemType,
|
||||
val languageType: LanguageType,
|
||||
|
||||
|
||||
val mainClassSimpleName: String = pluginCoordinates.run {
|
||||
name.adjustToClassName() ?: id.substringAfterLast('.').adjustToClassName()
|
||||
} ?: "PluginMain",
|
||||
val packageName: String = projectCoordinates.checkNotNull("projectCoordinates").groupId,
|
||||
)
|
||||
|
||||
fun <T : Any> T?.checkNotNull(name: String): T {
|
||||
contract {
|
||||
returns() implies (this@checkNotNull != null)
|
||||
}
|
||||
checkNotNull(this) {
|
||||
"$name is not yet initialized."
|
||||
}
|
||||
return this
|
||||
}
|
@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.intellij.wizard
|
||||
|
||||
import com.intellij.ide.starters.local.StarterContextProvider
|
||||
import com.intellij.ide.starters.local.wizard.StarterInitialStep
|
||||
import com.intellij.ide.starters.shared.JAVA_STARTER_LANGUAGE
|
||||
import com.intellij.ide.starters.shared.KOTLIN_STARTER_LANGUAGE
|
||||
import com.intellij.ide.starters.shared.ValidationFunctions
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.observable.util.trim
|
||||
import com.intellij.openapi.ui.ComboBox
|
||||
import com.intellij.openapi.ui.MessageType
|
||||
import com.intellij.openapi.ui.popup.Balloon
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory
|
||||
import com.intellij.ui.SimpleTextAttributes.GRAYED_ITALIC_ATTRIBUTES
|
||||
import com.intellij.ui.awt.RelativePoint
|
||||
import com.intellij.ui.dsl.builder.*
|
||||
import net.mamoe.mirai.console.intellij.wizard.MiraiProjectWizardBundle.message
|
||||
import org.jetbrains.concurrency.Promise
|
||||
import org.jetbrains.concurrency.runAsync
|
||||
|
||||
private val log = logger<MiraiProjectWizardInitialStep>()
|
||||
|
||||
class MiraiProjectWizardInitialStep(contextProvider: StarterContextProvider) : StarterInitialStep(contextProvider) {
|
||||
private val pluginVersionProperty = propertyGraph.property("0.1.0")
|
||||
private val pluginNameProperty = propertyGraph.lazyProperty { "" }
|
||||
private val pluginIdProperty = propertyGraph.lazyProperty { "" }
|
||||
private val pluginAuthorProperty = propertyGraph.lazyProperty { System.getProperty("user.name") }
|
||||
private val pluginDependenciesProperty = propertyGraph.lazyProperty { "" }
|
||||
private val pluginInfoProperty = propertyGraph.lazyProperty { "" }
|
||||
private val miraiVersionKindProperty = propertyGraph.property(MiraiVersionKind.Stable)
|
||||
private val miraiVersionProperty = propertyGraph.property("0.1.0")
|
||||
|
||||
var pluginVersion by pluginVersionProperty.trim()
|
||||
var pluginName by pluginNameProperty.trim()
|
||||
var pluginId by pluginIdProperty.trim()
|
||||
var pluginAuthor by pluginAuthorProperty.trim()
|
||||
var pluginDependencies by pluginDependenciesProperty.trim()
|
||||
var pluginInfo by pluginInfoProperty.trim()
|
||||
|
||||
var miraiVersionKind by miraiVersionKindProperty
|
||||
var miraiVersion by miraiVersionProperty
|
||||
|
||||
private lateinit var miraiVersionCell: Cell<ComboBox<String>>
|
||||
|
||||
override fun addFieldsAfter(layout: Panel) {
|
||||
layout.group(message("title.plugin.description")) {
|
||||
row(message("label.plugin.id")) {
|
||||
textField()
|
||||
.withSpecialValidation(
|
||||
ValidationFunctions.CHECK_NOT_EMPTY,
|
||||
)
|
||||
.bindText(pluginIdProperty)
|
||||
rowComment(message("comment.plugin.id"))
|
||||
|
||||
pluginIdProperty.dependsOn(groupIdProperty) { "$groupId.$artifactId" }
|
||||
pluginIdProperty.dependsOn(artifactIdProperty) { "$groupId.$artifactId" }
|
||||
}
|
||||
|
||||
row(message("label.plugin.name")) {
|
||||
textField()
|
||||
.withSpecialValidation(
|
||||
ValidationFunctions.CHECK_NOT_EMPTY,
|
||||
MiraiValidations.CHECK_FORBIDDEN_PLUGIN_NAME,
|
||||
)
|
||||
.bindText(pluginNameProperty)
|
||||
|
||||
pluginNameProperty.dependsOn(artifactIdProperty) {
|
||||
artifactId.adjustToPresentationName()
|
||||
}
|
||||
|
||||
rowComment(message("comment.plugin.name"))
|
||||
}
|
||||
|
||||
row(message("label.plugin.version")) {
|
||||
textField()
|
||||
.withSpecialValidation(
|
||||
ValidationFunctions.CHECK_NOT_EMPTY,
|
||||
MiraiValidations.CHECK_ILLEGAL_VERSION_LINE
|
||||
)
|
||||
.bindText(pluginVersionProperty)
|
||||
rowComment(message("comment.plugin.version"))
|
||||
}
|
||||
row(message("label.plugin.author")) {
|
||||
textField().bindText(pluginAuthorProperty)
|
||||
}
|
||||
row(message("label.plugin.dependencies")) {
|
||||
expandableTextField()
|
||||
.withSpecialValidation(MiraiValidations.CHECK_PLUGIN_DEPENDENCIES_SEGMENT)
|
||||
.bindText(pluginDependenciesProperty)
|
||||
.component.emptyText.setText(message("text.hint.plugin.dependencies"), GRAYED_ITALIC_ATTRIBUTES)
|
||||
rowComment(message("comment.plugin.dependencies"))
|
||||
}
|
||||
row(message("label.plugin.info")) {
|
||||
expandableTextField().bindText(pluginInfoProperty)
|
||||
.component.emptyText.setText(message("text.hint.plugin.info"), GRAYED_ITALIC_ATTRIBUTES)
|
||||
rowComment(message("comment.plugin.info"))
|
||||
}
|
||||
row(message("label.mirai.version")) {
|
||||
val miraiVersionKindCell = segmentedButton(MiraiVersionKind.values().toList()) { kind ->
|
||||
when (kind) {
|
||||
MiraiVersionKind.Stable -> message("label.version.stable")
|
||||
MiraiVersionKind.Prerelease -> message("label.version.prerelease")
|
||||
MiraiVersionKind.Nightly -> message("label.version.nightly")
|
||||
}
|
||||
}.bind(miraiVersionKindProperty)
|
||||
|
||||
miraiVersionCell = comboBox(listOf<String>())
|
||||
.enabled(false)
|
||||
.bindItem(miraiVersionProperty)
|
||||
|
||||
miraiVersionKindProperty.afterChange {
|
||||
if (!miraiVersionCell.component.isEnabled) return@afterChange
|
||||
|
||||
updateVersionItems(miraiVersionKindCell, miraiVersionCell)
|
||||
}
|
||||
|
||||
updateVersionItems(miraiVersionKindCell, miraiVersionCell)
|
||||
rowComment(message("comment.mirai.version"))
|
||||
}
|
||||
}
|
||||
|
||||
// Update default values
|
||||
|
||||
languageProperty.set(KOTLIN_STARTER_LANGUAGE)
|
||||
projectTypeProperty.set(MiraiModuleBuilder.GRADLE_KTS_PROJECT)
|
||||
pluginIdProperty.set("$groupId.$artifactId")
|
||||
pluginNameProperty.set(artifactId.adjustToPresentationName())
|
||||
}
|
||||
|
||||
override fun updateDataModel() {
|
||||
super.updateDataModel()
|
||||
|
||||
starterContext.putUserData(
|
||||
/* key = */ MiraiModuleBuilder.MIRAI_PROJECT_MODEL_KEY,
|
||||
/* value = */ MiraiProjectModel(
|
||||
projectCoordinates = ProjectCoordinates(
|
||||
groupId = groupId.trim(),
|
||||
artifactId = artifactId.trim(),
|
||||
version = pluginVersion.trim(),
|
||||
moduleName = entityName
|
||||
),
|
||||
pluginCoordinates = PluginCoordinates(
|
||||
id = pluginId.trim(),
|
||||
name = pluginName.trim(),
|
||||
author = pluginAuthor.trim(),
|
||||
info = pluginInfo.trim(),
|
||||
dependsOn = pluginDependencies.trim()
|
||||
),
|
||||
miraiVersion = miraiVersion,
|
||||
buildSystemType = when (val projectType = projectTypeProperty.get()) {
|
||||
MiraiModuleBuilder.GRADLE_KTS_PROJECT -> BuildSystemType.GradleKt
|
||||
MiraiModuleBuilder.GRADLE_GROOVY_PROJECT -> BuildSystemType.GradleGroovy
|
||||
else -> error("Unsupported project type: $projectType")
|
||||
},
|
||||
languageType = when (val language = languageProperty.get()) {
|
||||
KOTLIN_STARTER_LANGUAGE -> LanguageType.Kotlin
|
||||
JAVA_STARTER_LANGUAGE -> LanguageType.Java
|
||||
else -> error("Unsupported language type: $language")
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun validate(): Boolean {
|
||||
if (miraiVersion == message("label.mirai.version.loading")) {
|
||||
JBPopupFactory.getInstance()
|
||||
.createHtmlTextBalloonBuilder(
|
||||
message("error.please.wait.for.mirai.version"),
|
||||
MessageType.WARNING, null
|
||||
)
|
||||
.setFadeoutTime(3000)
|
||||
.createBalloon()
|
||||
.show(
|
||||
RelativePoint.getSouthWestOf(
|
||||
miraiVersionCell.component
|
||||
), Balloon.Position.atLeft
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
return super.validate()
|
||||
}
|
||||
|
||||
private fun updateVersionItems(
|
||||
miraiVersionKindCell: SegmentedButton<MiraiVersionKind>,
|
||||
miraiVersionCell: Cell<ComboBox<MiraiVersion>>
|
||||
): Promise<Set<MiraiVersion>?> {
|
||||
miraiVersionCell.component.isEditable = false
|
||||
miraiVersionKindCell.enabled(false) // disable the kind selector until the async operation finishes
|
||||
miraiVersionCell.enabled(false)
|
||||
|
||||
miraiVersionCell.component.removeAllItems()
|
||||
miraiVersionCell.component.addItem(message("label.mirai.version.loading"))
|
||||
|
||||
return runAsync {
|
||||
try {
|
||||
val list = MiraiVersionKind.getMiraiVersionList()
|
||||
miraiVersionCell.component.removeAllItems()
|
||||
list.filter { miraiVersionKind.isThatKind(it) }
|
||||
.forEach { v -> miraiVersionCell.component.addItem(v) }
|
||||
list
|
||||
} catch (e: Throwable) {
|
||||
JBPopupFactory.getInstance()
|
||||
.createHtmlTextBalloonBuilder(
|
||||
message("error.failed.to.download.mirai.version"),
|
||||
MessageType.ERROR, null
|
||||
)
|
||||
.setFadeoutTime(2000)
|
||||
.createBalloon()
|
||||
.show(
|
||||
RelativePoint.getSouthOf(
|
||||
miraiVersionCell.component
|
||||
), Balloon.Position.below
|
||||
)
|
||||
null
|
||||
}
|
||||
}.onError { log.error(it) }
|
||||
.onProcessed { versions ->
|
||||
miraiVersionCell.component.isEditable = versions == null
|
||||
miraiVersionKindCell.enabled(true)
|
||||
miraiVersionCell.enabled(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.adjustToPresentationName(): String {
|
||||
val result = buildString {
|
||||
var doCapitalization = true
|
||||
|
||||
fun Char.isAllowed() = isLetterOrDigit() || this in "_- "
|
||||
|
||||
for (char in this@adjustToPresentationName) {
|
||||
if (!char.isAllowed()) continue
|
||||
|
||||
if (doCapitalization) {
|
||||
when {
|
||||
char.isLetter() -> append(char.uppercase())
|
||||
char == '_' -> {}
|
||||
char == '-' -> {}
|
||||
else -> append(char)
|
||||
}
|
||||
doCapitalization = false
|
||||
} else {
|
||||
if (char in "_- ") {
|
||||
doCapitalization = true
|
||||
append(' ')
|
||||
} else {
|
||||
append(char)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.trim()
|
||||
|
||||
return result
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.intellij.wizard
|
||||
|
||||
import com.intellij.ide.starters.shared.TextValidationFunction
|
||||
import net.mamoe.mirai.console.compiler.common.CheckerConstants
|
||||
import net.mamoe.mirai.console.intellij.util.RequirementHelper
|
||||
import net.mamoe.mirai.console.intellij.util.RequirementParser
|
||||
import net.mamoe.mirai.console.intellij.wizard.MiraiProjectWizardBundle.message
|
||||
|
||||
object MiraiValidations {
|
||||
val CHECK_FORBIDDEN_PLUGIN_NAME = TextValidationFunction { text ->
|
||||
val lowercaseName = text.lowercase().trim()
|
||||
val illegal =
|
||||
CheckerConstants.PLUGIN_FORBIDDEN_NAMES.firstOrNull { it == lowercaseName }
|
||||
if (illegal != null) {
|
||||
message("validation.plugin.name.forbidden.character", illegal)
|
||||
} else null
|
||||
}
|
||||
|
||||
val CHECK_PLUGIN_ID = TextValidationFunction { text ->
|
||||
if (!CheckerConstants.PLUGIN_ID_REGEX.matches(text.trim())) {
|
||||
message("validation.illegal.plugin.id", text)
|
||||
} else null
|
||||
}
|
||||
|
||||
val CHECK_ILLEGAL_VERSION_LINE = TextValidationFunction { text ->
|
||||
checkVersionLine(text)?.let {
|
||||
message("validation.illegal.version", text, it)
|
||||
}
|
||||
}
|
||||
|
||||
val CHECK_PLUGIN_DEPENDENCIES_LINE = TextValidationFunction { text ->
|
||||
try {
|
||||
val trim = text.trim()
|
||||
val dep = PluginDependency.parseFromString(trim)
|
||||
if (!CheckerConstants.PLUGIN_ID_REGEX.matches(dep.id)) {
|
||||
return@TextValidationFunction message("validation.illegal.plugin.id", dep.id)
|
||||
}
|
||||
|
||||
dep.versionRequirement?.let { checkVersionRequirementLine(it) }?.let {
|
||||
return@TextValidationFunction message("validation.illegal.version", it)
|
||||
}
|
||||
|
||||
null // no error
|
||||
} catch (e: IllegalArgumentException) {
|
||||
message("validation.illegal.version", text, e.message ?: message("no.error.message"))
|
||||
}
|
||||
}
|
||||
|
||||
val CHECK_PLUGIN_DEPENDENCIES_SEGMENT = TextValidationFunction { text ->
|
||||
text.lineSequence()
|
||||
.map { it.trim() }
|
||||
.filter { it.isNotEmpty() }
|
||||
.map { CHECK_PLUGIN_DEPENDENCIES_LINE.checkText(it) }
|
||||
.firstOrNull()
|
||||
}
|
||||
|
||||
/**
|
||||
* Check multiple lines and returns information about the first illegal one.
|
||||
*/
|
||||
val CHECK_ILLEGAL_VERSION_SEGMENT = TextValidationFunction { text ->
|
||||
text.lineSequence()
|
||||
.map { it.trim() }
|
||||
.filter { it.isNotEmpty() }
|
||||
.mapNotNull { CHECK_ILLEGAL_VERSION_LINE.checkText(text) }
|
||||
.firstOrNull()
|
||||
}
|
||||
|
||||
private class PluginDependency @JvmOverloads constructor(
|
||||
val id: String,
|
||||
val versionRequirement: String? = null,
|
||||
) {
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* Frozen version of [net.mamoe.mirai.console.plugin.description.PluginDescription.Companion.parseFromString] from `2.11.0-M2.2`.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun parseFromString(string: String): PluginDependency {
|
||||
// val optional = string.endsWith('?')
|
||||
val (id, version) = string.removeSuffix("?").let { rule ->
|
||||
if (rule.contains(':')) {
|
||||
rule.substringBeforeLast(':') to rule.substringAfterLast(':')
|
||||
} else {
|
||||
rule to null
|
||||
}
|
||||
}
|
||||
return PluginDependency(id, version)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkVersionLine(version: String): String? {
|
||||
return checkVersionRequirementLine(version) // for simplicity
|
||||
}
|
||||
|
||||
private fun checkVersionRequirementLine(versionRequirement: String): String? {
|
||||
kotlin.runCatching {
|
||||
RequirementHelper.RequirementChecker.processLine(
|
||||
RequirementParser.TokenReader(
|
||||
versionRequirement
|
||||
)
|
||||
)
|
||||
}.onFailure { return it.message ?: message("no.error.message") }
|
||||
return null
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package net.mamoe.mirai.console.intellij.creator
|
||||
package net.mamoe.mirai.console.intellij.wizard
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.util.text.SemVer
|
||||
@ -24,7 +24,7 @@ enum class MiraiVersionKind {
|
||||
},
|
||||
Prerelease {
|
||||
override fun isThatKind(version: String): Boolean =
|
||||
version.contains("-M") || version.contains("-RC")
|
||||
Stable.isThatKind(version) || version.contains("-M") || version.contains("-RC")
|
||||
},
|
||||
Nightly {
|
||||
override fun isThatKind(version: String): Boolean = true // version.contains("-dev")
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.intellij.wizard
|
||||
|
||||
import com.intellij.AbstractBundle
|
||||
import org.jetbrains.annotations.Nls
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.annotations.PropertyKey
|
||||
import java.util.function.Supplier
|
||||
|
||||
@NonNls
|
||||
private const val BUNDLE = "messages.MiraiProjectWizardBundle"
|
||||
|
||||
object MiraiProjectWizardBundle : AbstractBundle(BUNDLE) {
|
||||
@Nls
|
||||
@JvmStatic
|
||||
fun message(@NonNls @PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): String =
|
||||
getMessage(key, *params)
|
||||
|
||||
@JvmStatic
|
||||
fun messagePointer(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): Supplier<String> {
|
||||
return getLazyMessage(key, *params)
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
package net.mamoe.mirai.console.intellij.wizard
|
||||
|
||||
import com.intellij.ide.fileTemplates.FileTemplate
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager
|
||||
import com.intellij.ide.starters.local.GeneratorAsset
|
||||
import com.intellij.ide.starters.local.GeneratorEmptyDirectory
|
||||
import com.intellij.ide.starters.local.GeneratorTemplateFile
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
import net.mamoe.mirai.console.intellij.assets.FT
|
||||
|
||||
sealed class ProjectCreator(
|
||||
val model: MiraiProjectModel,
|
||||
) {
|
||||
private val manager get() = FileTemplateManager.getInstance(ProjectManager.getInstance().defaultProject)
|
||||
|
||||
fun getTemplate(name: String): FileTemplate = manager.getCodeTemplate(name)
|
||||
|
||||
abstract fun collectAssets(
|
||||
collect: (GeneratorAsset) -> Unit,
|
||||
)
|
||||
}
|
||||
|
||||
sealed class GradleProjectCreator(
|
||||
model: MiraiProjectModel,
|
||||
) : ProjectCreator(model) {
|
||||
override fun collectAssets(
|
||||
collect: (GeneratorAsset) -> Unit
|
||||
) {
|
||||
collect(GeneratorEmptyDirectory("src/main/${model.languageType.sourceSetDirName}"))
|
||||
collect(GeneratorEmptyDirectory("src/main/resources"))
|
||||
|
||||
collect(GeneratorTemplateFile(model.languageType.pluginMainClassFile(this)))
|
||||
|
||||
collect(GeneratorTemplateFile(".gitignore", getTemplate(FT.Gitignore)))
|
||||
collect(GeneratorTemplateFile("gradle.properties", getTemplate(FT.GradleProperties)))
|
||||
collect(GeneratorTemplateFile("src/test/kotlin/RunTerminal.kt", getTemplate(FT.RunTerminal)))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun GeneratorTemplateFile(targetFileName: NamedFile): GeneratorTemplateFile {
|
||||
return GeneratorTemplateFile(targetFileName.path, targetFileName.template)
|
||||
}
|
||||
|
||||
|
||||
class GradleKotlinProjectCreator(
|
||||
model: MiraiProjectModel,
|
||||
) : GradleProjectCreator(
|
||||
model,
|
||||
) {
|
||||
override fun collectAssets(
|
||||
collect: (GeneratorAsset) -> Unit
|
||||
) {
|
||||
super.collectAssets(collect)
|
||||
collect(GeneratorTemplateFile("build.gradle.kts", getTemplate(FT.BuildGradleKts)))
|
||||
collect(GeneratorTemplateFile("settings.gradle.kts", getTemplate(FT.SettingsGradleKts)))
|
||||
}
|
||||
}
|
||||
|
||||
class GradleGroovyProjectCreator(
|
||||
model: MiraiProjectModel,
|
||||
) : GradleProjectCreator(
|
||||
model,
|
||||
) {
|
||||
override fun collectAssets(
|
||||
collect: (GeneratorAsset) -> Unit
|
||||
) {
|
||||
super.collectAssets(collect)
|
||||
collect(GeneratorTemplateFile("build.gradle", getTemplate(FT.BuildGradle)))
|
||||
collect(GeneratorTemplateFile("settings.gradle", getTemplate(FT.SettingsGradle)))
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
package creator
|
||||
|
||||
import net.mamoe.mirai.console.intellij.creator.sortVersionsDescending
|
||||
import net.mamoe.mirai.console.intellij.wizard.sortVersionsDescending
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
@ -1,14 +1,18 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.intellij.creator.tasks
|
||||
|
||||
import net.mamoe.mirai.console.intellij.diagnostics.adjustToClassName
|
||||
import net.mamoe.mirai.console.intellij.diagnostics.isValidPackageName
|
||||
import net.mamoe.mirai.console.intellij.diagnostics.isValidQualifiedClassName
|
||||
import net.mamoe.mirai.console.intellij.diagnostics.isValidSimpleClassName
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
Loading…
Reference in New Issue
Block a user