Skip to content

Commit

Permalink
Merge branch '2023.1' into 2023.2
Browse files Browse the repository at this point in the history
  • Loading branch information
RedNesto committed Aug 13, 2023
2 parents 2b72765 + 5ce6324 commit d1a0c0f
Show file tree
Hide file tree
Showing 8 changed files with 259 additions and 216 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ kotlin.code.style=official
ideaVersion = 2023.2
ideaVersionName = 2023.2

coreVersion = 1.6.9
coreVersion = 1.6.10
downloadIdeaSources = true

pluginTomlVersion = 232.8660.88
Expand Down
6 changes: 1 addition & 5 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ Minecraft Development for IntelliJ
<td align="right"><b>Main Build</b></td>
<td colspan="2"><a href="https://ci.denwav.dev/viewType.html?buildTypeId=MinecraftDev_Build"><img src="https://ci.denwav.dev/app/rest/builds/buildType:(id:MinecraftDev_Build)/statusIcon.svg" alt="Teamcity Build Status" /></a></td>
</tr>
<tr>
<td align="left">2022.2</td>
<td align="left"><a href="https://ci.denwav.dev/viewType.html?buildTypeId=MinecraftDev_Nightly_20222"><img src="https://ci.denwav.dev/app/rest/builds/buildType:(id:MinecraftDev_Nightly_20222)/statusIcon.svg" alt="2022.2 Nightly Status" /></a></td>
</tr>
<tr>
<td align="left">2022.3</td>
<td align="left"><a href="https://ci.denwav.dev/viewType.html?buildTypeId=MinecraftDev_Nightly_20223"><img src="https://ci.denwav.dev/app/rest/builds/buildType:(id:MinecraftDev_Nightly_20223)/statusIcon.svg" alt="2022.3 Nightly Status" /></a></td>
Expand All @@ -35,7 +31,7 @@ Minecraft Development for IntelliJ
</tr>
</table>

Info and Documentation [![Current Release](https://img.shields.io/badge/release-1.6.8-orange.svg?style=flat-square)](https://plugins.jetbrains.com/plugin/8327)
Info and Documentation [![Current Release](https://img.shields.io/badge/release-1.6.10-orange.svg?style=flat-square)](https://plugins.jetbrains.com/plugin/8327)
----------------------

<a href="https://discord.gg/j6UNcfr"><img src="https://i.imgur.com/JXu9C1G.png" height="48px"></img></a>
Expand Down
245 changes: 44 additions & 201 deletions src/main/kotlin/platform/fabric/creator/asset-steps.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

package com.demonwav.mcdev.platform.fabric.creator

import com.demonwav.mcdev.asset.MCDevBundle
import com.demonwav.mcdev.creator.JdkProjectSetupFinalizer
import com.demonwav.mcdev.creator.addLicense
import com.demonwav.mcdev.creator.addTemplates
Expand All @@ -43,69 +42,20 @@ import com.demonwav.mcdev.platform.fabric.util.FabricConstants
import com.demonwav.mcdev.platform.forge.inspections.sideonly.Side
import com.demonwav.mcdev.util.MinecraftTemplates.Companion.FABRIC_MIXINS_JSON_TEMPLATE
import com.demonwav.mcdev.util.MinecraftTemplates.Companion.FABRIC_MOD_JSON_TEMPLATE
import com.demonwav.mcdev.util.addImplements
import com.demonwav.mcdev.util.addMethod
import com.demonwav.mcdev.util.invokeLater
import com.demonwav.mcdev.util.runWriteAction
import com.demonwav.mcdev.util.runWriteTaskInSmartMode
import com.demonwav.mcdev.util.toJavaClassName
import com.demonwav.mcdev.util.toPackageName
import com.intellij.codeInsight.actions.ReformatCodeProcessor
import com.intellij.codeInsight.generation.OverrideImplementUtil
import com.intellij.ide.starters.local.GeneratorEmptyDirectory
import com.intellij.ide.util.EditorHelper
import com.intellij.ide.wizard.NewProjectWizardStep
import com.intellij.json.psi.JsonArray
import com.intellij.json.psi.JsonElementGenerator
import com.intellij.json.psi.JsonFile
import com.intellij.json.psi.JsonObject
import com.intellij.openapi.fileEditor.impl.NonProjectFileWritingAccessProvider
import com.intellij.openapi.application.WriteAction
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.psi.JavaDirectoryService
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiManager
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.util.IncorrectOperationException
import java.nio.file.Path
import java.util.concurrent.CountDownLatch

class FabricDumbModeFilesStep(parent: NewProjectWizardStep) : AbstractLongRunningAssetsStep(parent) {
override val description = "Adding Fabric project files (phase 1)"

override fun setupAssets(project: Project) {
val buildSystemProps = findStep<BuildSystemPropertiesStep<*>>()
val modId = data.getUserData(AbstractModIdStep.KEY) ?: return
val useMixins = data.getUserData(UseMixinsStep.KEY) ?: false
val javaVersion = findStep<JdkProjectSetupFinalizer>().preferredJdk.ordinal
const val MAGIC_DEFERRED_INIT_FILE = ".hello_fabric_from_mcdev"

if (useMixins) {
val packageName =
"${buildSystemProps.groupId.toPackageName()}.${modId.toPackageName()}.mixin"
assets.addTemplateProperties(
"PACKAGE_NAME" to packageName,
"JAVA_VERSION" to javaVersion,
)
val mixinsJsonFile = "src/main/resources/$modId.mixins.json"
assets.addTemplates(project, mixinsJsonFile to FABRIC_MIXINS_JSON_TEMPLATE)
}

assets.addLicense(project)

assets.addAssets(
GeneratorEmptyDirectory("src/main/java"),
GeneratorEmptyDirectory("src/main/resources"),
)
}
}

class FabricSmartModeFilesStep(parent: NewProjectWizardStep) : AbstractLongRunningAssetsStep(parent) {
override val description = "Adding Fabric project files (phase 2)"

private lateinit var entryPoints: List<EntryPoint>
class FabricBaseFilesStep(parent: NewProjectWizardStep) : AbstractLongRunningAssetsStep(parent) {
override val description = "Adding Fabric project files (phase 1)"

override fun setupAssets(project: Project) {
val buildSystemProps = findStep<BuildSystemPropertiesStep<*>>()
Expand All @@ -124,14 +74,6 @@ class FabricSmartModeFilesStep(parent: NewProjectWizardStep) : AbstractLongRunni
val apiVersion = data.getUserData(FabricVersionChainStep.API_VERSION_KEY)
val useMixins = data.getUserData(UseMixinsStep.KEY) ?: false

val packageName = "${buildSystemProps.groupId.toPackageName()}.${modId.toPackageName()}"
val mainClassName = "$packageName.${modName.toJavaClassName()}"
val clientClassName = "$packageName.client.${modName.toJavaClassName()}Client"
entryPoints = listOf(
EntryPoint("main", EntryPoint.Type.CLASS, mainClassName, FabricConstants.MOD_INITIALIZER),
EntryPoint("client", EntryPoint.Type.CLASS, clientClassName, FabricConstants.CLIENT_MOD_INITIALIZER),
) // TODO: un-hardcode?

assets.addTemplateProperties(
"ARTIFACT_ID" to buildSystemProps.artifactId,
"MOD_ID" to modId,
Expand All @@ -149,153 +91,54 @@ class FabricSmartModeFilesStep(parent: NewProjectWizardStep) : AbstractLongRunni
}

if (useMixins) {
assets.addTemplateProperties("MIXINS" to "true")
}

assets.addTemplates(project, "src/main/resources/fabric.mod.json" to FABRIC_MOD_JSON_TEMPLATE)
}

private fun fixupFabricModJson(project: Project) {
val authors = data.getUserData(AuthorsStep.KEY) ?: emptyList()
val website = data.getUserData(WebsiteStep.KEY)
val repo = data.getUserData(RepositoryStep.KEY)

val fabricModJsonFile =
VfsUtil.findFile(Path.of(context.projectFileDirectory, "src", "main", "resources", "fabric.mod.json"), true)
?: return
val jsonFile = PsiManager.getInstance(project).findFile(fabricModJsonFile) as? JsonFile ?: return
val json = jsonFile.topLevelValue as? JsonObject ?: return
val generator = JsonElementGenerator(project)

NonProjectFileWritingAccessProvider.allowWriting(listOf(fabricModJsonFile))
jsonFile.runWriteAction {
(json.findProperty("authors")?.value as? JsonArray)?.let { authorsArray ->
for (i in authors.indices) {
if (i != 0) {
authorsArray.addBefore(generator.createComma(), authorsArray.lastChild)
}
authorsArray.addBefore(generator.createStringLiteral(authors[i]), authorsArray.lastChild)
}
}

(json.findProperty("contact")?.value as? JsonObject)?.let { contactObject ->
val properties = mutableListOf<Pair<String, String>>()
if (!website.isNullOrBlank()) {
properties += "website" to website
}
if (!repo.isNullOrBlank()) {
properties += "repo" to repo
}
for (i in properties.indices) {
if (i != 0) {
contactObject.addBefore(generator.createComma(), contactObject.lastChild)
}
val key = StringUtil.escapeStringCharacters(properties[i].first)
val value = "\"" + StringUtil.escapeStringCharacters(properties[i].second) + "\""
contactObject.addBefore(generator.createProperty(key, value), contactObject.lastChild)
}
}

(json.findProperty("entrypoints")?.value as? JsonObject)?.let { entryPointsObject ->
val entryPointsByCategory = entryPoints
.groupBy { it.category }
.asSequence()
.sortedBy { it.key }
.toList()
for (i in entryPointsByCategory.indices) {
val entryPointCategory = entryPointsByCategory[i]
if (i != 0) {
entryPointsObject.addBefore(generator.createComma(), entryPointsObject.lastChild)
}
val values = generator.createValue<JsonArray>("[]")
for (j in entryPointCategory.value.indices) {
if (j != 0) {
values.addBefore(generator.createComma(), values.lastChild)
}
val entryPointReference = entryPointCategory.value[j].computeReference(project)
val value = generator.createStringLiteral(entryPointReference)
values.addBefore(value, values.lastChild)
}
val key = StringUtil.escapeStringCharacters(entryPointCategory.key)
val prop = generator.createProperty(key, "[]")
prop.value?.replace(values)
entryPointsObject.addBefore(prop, entryPointsObject.lastChild)
}
}

ReformatCodeProcessor(project, jsonFile, null, false).run()
val packageName =
"${buildSystemProps.groupId.toPackageName()}.${modId.toPackageName()}.mixin"
assets.addTemplateProperties(
"MIXINS" to "true",
"MIXIN_PACKAGE_NAME" to packageName,
)
val mixinsJsonFile = "src/main/resources/$modId.mixins.json"
assets.addTemplates(project, mixinsJsonFile to FABRIC_MIXINS_JSON_TEMPLATE)
}
}

private fun createEntryPoints(project: Project) {
val root = VfsUtil.findFile(Path.of(context.projectFileDirectory), true) ?: return
val psiManager = PsiManager.getInstance(project)

val generatedClasses = mutableSetOf<PsiClass>()

for (entryPoint in entryPoints) {
// find the class, and create it if it doesn't exist
val clazz = JavaPsiFacade.getInstance(project).findClass(
entryPoint.className,
GlobalSearchScope.projectScope(project),
) ?: run {
val packageName = entryPoint.className.substringBeforeLast('.', missingDelimiterValue = "")
val className = entryPoint.className.substringAfterLast('.')
assets.addLicense(project)

val dir = VfsUtil.createDirectoryIfMissing(root, "src/main/java/${packageName.replace('.', '/')}")
val psiDir = psiManager.findDirectory(dir) ?: return@run null
try {
JavaDirectoryService.getInstance().createClass(psiDir, className)
} catch (e: IncorrectOperationException) {
invokeLater {
val message = MCDevBundle.message(
"intention.error.cannot.create.class.message",
className,
e.localizedMessage,
)
Messages.showErrorDialog(
project,
message,
MCDevBundle.message("intention.error.cannot.create.class.title"),
)
}
return
}
} ?: continue
assets.addAssets(
GeneratorEmptyDirectory("src/main/java"),
GeneratorEmptyDirectory("src/main/resources"),
)

clazz.containingFile.runWriteAction {
clazz.addImplements(entryPoint.interfaceName)
assets.addTemplates(project, "src/main/resources/fabric.mod.json" to FABRIC_MOD_JSON_TEMPLATE)

val methodsToImplement = OverrideImplementUtil.getMethodsToOverrideImplement(clazz, true)
val methods = OverrideImplementUtil.overrideOrImplementMethodCandidates(clazz, methodsToImplement, true)
for (method in methods) {
clazz.addMethod(method)
}
}
WriteAction.runAndWait<Throwable> {
val dir = VfsUtil.createDirectoryIfMissing(
LocalFileSystem.getInstance(),
"${assets.outputDirectory}/.gradle",
)
?: throw IllegalStateException("Unable to create .gradle directory")
val file = dir.findOrCreateChildData(this, MAGIC_DEFERRED_INIT_FILE)

generatedClasses += clazz
}
val authors = data.getUserData(AuthorsStep.KEY) ?: emptyList()
val website = data.getUserData(WebsiteStep.KEY)
val repo = data.getUserData(RepositoryStep.KEY)

for (clazz in generatedClasses) {
ReformatCodeProcessor(project, clazz.containingFile, null, false).run()
EditorHelper.openInEditor(clazz)
}
}
val packageName = "${buildSystemProps.groupId.toPackageName()}.${modId.toPackageName()}"
val mainClassName = "$packageName.${modName.toJavaClassName()}"
val clientClassName = "$packageName.client.${modName.toJavaClassName()}Client"

override fun perform(project: Project) {
super.perform(project)
val latch = CountDownLatch(1)
assets.runWhenCreated(project) {
project.runWriteTaskInSmartMode {
try {
fixupFabricModJson(project)
createEntryPoints(project)
} finally {
latch.countDown()
}
}
val entrypoints = listOf(
"main,${EntryPoint.Type.CLASS.name},$mainClassName,${FabricConstants.MOD_INITIALIZER}",
"client,${EntryPoint.Type.CLASS.name},$clientClassName,${FabricConstants.CLIENT_MOD_INITIALIZER}",
)
val fileContents = """
${authors.joinToString(",")}
$website
$repo
${entrypoints.joinToString(";")}
""".trimIndent() // TODO: un-hardcode?

VfsUtil.saveText(file, fileContents)
}
latch.await()
}
}

Expand Down
5 changes: 1 addition & 4 deletions src/main/kotlin/platform/fabric/creator/ui-steps.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import com.demonwav.mcdev.creator.step.NewProjectWizardChainStep.Companion.nextS
import com.demonwav.mcdev.creator.step.RepositoryStep
import com.demonwav.mcdev.creator.step.UseMixinsStep
import com.demonwav.mcdev.creator.step.VersionChainComboBox
import com.demonwav.mcdev.creator.step.WaitForSmartModeStep
import com.demonwav.mcdev.creator.step.WebsiteStep
import com.demonwav.mcdev.platform.fabric.util.FabricApiVersions
import com.demonwav.mcdev.platform.fabric.util.FabricVersions
Expand Down Expand Up @@ -80,10 +79,8 @@ class FabricPlatformStep(
.nextStep(::LicenseStep)
.nextStep(::FabricOptionalSettingsStep)
.nextStep(::FabricBuildSystemStep)
.nextStep(::FabricDumbModeFilesStep)
.nextStep(::FabricBaseFilesStep)
.nextStep(::FabricPostBuildSystemStep)
.nextStep(::WaitForSmartModeStep)
.nextStep(::FabricSmartModeFilesStep)
}

class Factory : ModPlatformStep.Factory {
Expand Down
Loading

0 comments on commit d1a0c0f

Please sign in to comment.