2020
2121package com.demonwav.mcdev.platform.fabric.creator
2222
23- import com.demonwav.mcdev.asset.MCDevBundle
2423import com.demonwav.mcdev.creator.JdkProjectSetupFinalizer
2524import com.demonwav.mcdev.creator.addLicense
2625import com.demonwav.mcdev.creator.addTemplates
@@ -43,69 +42,20 @@ import com.demonwav.mcdev.platform.fabric.util.FabricConstants
4342import com.demonwav.mcdev.platform.forge.inspections.sideonly.Side
4443import com.demonwav.mcdev.util.MinecraftTemplates.Companion.FABRIC_MIXINS_JSON_TEMPLATE
4544import com.demonwav.mcdev.util.MinecraftTemplates.Companion.FABRIC_MOD_JSON_TEMPLATE
46- import com.demonwav.mcdev.util.addImplements
47- import com.demonwav.mcdev.util.addMethod
48- import com.demonwav.mcdev.util.invokeLater
49- import com.demonwav.mcdev.util.runWriteAction
50- import com.demonwav.mcdev.util.runWriteTaskInSmartMode
5145import com.demonwav.mcdev.util.toJavaClassName
5246import com.demonwav.mcdev.util.toPackageName
53- import com.intellij.codeInsight.actions.ReformatCodeProcessor
54- import com.intellij.codeInsight.generation.OverrideImplementUtil
5547import com.intellij.ide.starters.local.GeneratorEmptyDirectory
56- import com.intellij.ide.util.EditorHelper
5748import com.intellij.ide.wizard.NewProjectWizardStep
58- import com.intellij.json.psi.JsonArray
59- import com.intellij.json.psi.JsonElementGenerator
60- import com.intellij.json.psi.JsonFile
61- import com.intellij.json.psi.JsonObject
62- import com.intellij.openapi.fileEditor.impl.NonProjectFileWritingAccessProvider
49+ import com.intellij.openapi.application.WriteAction
6350import com.intellij.openapi.project.Project
64- import com.intellij.openapi.ui.Messages
6551import com.intellij.openapi.util.text.StringUtil
52+ import com.intellij.openapi.vfs.LocalFileSystem
6653import com.intellij.openapi.vfs.VfsUtil
67- import com.intellij.psi.JavaDirectoryService
68- import com.intellij.psi.JavaPsiFacade
69- import com.intellij.psi.PsiClass
70- import com.intellij.psi.PsiManager
71- import com.intellij.psi.search.GlobalSearchScope
72- import com.intellij.util.IncorrectOperationException
73- import java.nio.file.Path
74- import java.util.concurrent.CountDownLatch
7554
76- class FabricDumbModeFilesStep (parent : NewProjectWizardStep ) : AbstractLongRunningAssetsStep(parent) {
77- override val description = " Adding Fabric project files (phase 1)"
78-
79- override fun setupAssets (project : Project ) {
80- val buildSystemProps = findStep<BuildSystemPropertiesStep <* >>()
81- val modId = data.getUserData(AbstractModIdStep .KEY ) ? : return
82- val useMixins = data.getUserData(UseMixinsStep .KEY ) ? : false
83- val javaVersion = findStep<JdkProjectSetupFinalizer >().preferredJdk.ordinal
55+ const val MAGIC_DEFERRED_INIT_FILE = " .hello_fabric_from_mcdev"
8456
85- if (useMixins) {
86- val packageName =
87- " ${buildSystemProps.groupId.toPackageName()} .${modId.toPackageName()} .mixin"
88- assets.addTemplateProperties(
89- " PACKAGE_NAME" to packageName,
90- " JAVA_VERSION" to javaVersion,
91- )
92- val mixinsJsonFile = " src/main/resources/$modId .mixins.json"
93- assets.addTemplates(project, mixinsJsonFile to FABRIC_MIXINS_JSON_TEMPLATE )
94- }
95-
96- assets.addLicense(project)
97-
98- assets.addAssets(
99- GeneratorEmptyDirectory (" src/main/java" ),
100- GeneratorEmptyDirectory (" src/main/resources" ),
101- )
102- }
103- }
104-
105- class FabricSmartModeFilesStep (parent : NewProjectWizardStep ) : AbstractLongRunningAssetsStep(parent) {
106- override val description = " Adding Fabric project files (phase 2)"
107-
108- private lateinit var entryPoints: List <EntryPoint >
57+ class FabricBaseFilesStep (parent : NewProjectWizardStep ) : AbstractLongRunningAssetsStep(parent) {
58+ override val description = " Adding Fabric project files (phase 1)"
10959
11060 override fun setupAssets (project : Project ) {
11161 val buildSystemProps = findStep<BuildSystemPropertiesStep <* >>()
@@ -124,14 +74,6 @@ class FabricSmartModeFilesStep(parent: NewProjectWizardStep) : AbstractLongRunni
12474 val apiVersion = data.getUserData(FabricVersionChainStep .API_VERSION_KEY )
12575 val useMixins = data.getUserData(UseMixinsStep .KEY ) ? : false
12676
127- val packageName = " ${buildSystemProps.groupId.toPackageName()} .${modId.toPackageName()} "
128- val mainClassName = " $packageName .${modName.toJavaClassName()} "
129- val clientClassName = " $packageName .client.${modName.toJavaClassName()} Client"
130- entryPoints = listOf (
131- EntryPoint (" main" , EntryPoint .Type .CLASS , mainClassName, FabricConstants .MOD_INITIALIZER ),
132- EntryPoint (" client" , EntryPoint .Type .CLASS , clientClassName, FabricConstants .CLIENT_MOD_INITIALIZER ),
133- ) // TODO: un-hardcode?
134-
13577 assets.addTemplateProperties(
13678 " ARTIFACT_ID" to buildSystemProps.artifactId,
13779 " MOD_ID" to modId,
@@ -149,153 +91,54 @@ class FabricSmartModeFilesStep(parent: NewProjectWizardStep) : AbstractLongRunni
14991 }
15092
15193 if (useMixins) {
152- assets.addTemplateProperties(" MIXINS" to " true" )
153- }
154-
155- assets.addTemplates(project, " src/main/resources/fabric.mod.json" to FABRIC_MOD_JSON_TEMPLATE )
156- }
157-
158- private fun fixupFabricModJson (project : Project ) {
159- val authors = data.getUserData(AuthorsStep .KEY ) ? : emptyList()
160- val website = data.getUserData(WebsiteStep .KEY )
161- val repo = data.getUserData(RepositoryStep .KEY )
162-
163- val fabricModJsonFile =
164- VfsUtil .findFile(Path .of(context.projectFileDirectory, " src" , " main" , " resources" , " fabric.mod.json" ), true )
165- ? : return
166- val jsonFile = PsiManager .getInstance(project).findFile(fabricModJsonFile) as ? JsonFile ? : return
167- val json = jsonFile.topLevelValue as ? JsonObject ? : return
168- val generator = JsonElementGenerator (project)
169-
170- NonProjectFileWritingAccessProvider .allowWriting(listOf (fabricModJsonFile))
171- jsonFile.runWriteAction {
172- (json.findProperty(" authors" )?.value as ? JsonArray )?.let { authorsArray ->
173- for (i in authors.indices) {
174- if (i != 0 ) {
175- authorsArray.addBefore(generator.createComma(), authorsArray.lastChild)
176- }
177- authorsArray.addBefore(generator.createStringLiteral(authors[i]), authorsArray.lastChild)
178- }
179- }
180-
181- (json.findProperty(" contact" )?.value as ? JsonObject )?.let { contactObject ->
182- val properties = mutableListOf<Pair <String , String >>()
183- if (! website.isNullOrBlank()) {
184- properties + = " website" to website
185- }
186- if (! repo.isNullOrBlank()) {
187- properties + = " repo" to repo
188- }
189- for (i in properties.indices) {
190- if (i != 0 ) {
191- contactObject.addBefore(generator.createComma(), contactObject.lastChild)
192- }
193- val key = StringUtil .escapeStringCharacters(properties[i].first)
194- val value = " \" " + StringUtil .escapeStringCharacters(properties[i].second) + " \" "
195- contactObject.addBefore(generator.createProperty(key, value), contactObject.lastChild)
196- }
197- }
198-
199- (json.findProperty(" entrypoints" )?.value as ? JsonObject )?.let { entryPointsObject ->
200- val entryPointsByCategory = entryPoints
201- .groupBy { it.category }
202- .asSequence()
203- .sortedBy { it.key }
204- .toList()
205- for (i in entryPointsByCategory.indices) {
206- val entryPointCategory = entryPointsByCategory[i]
207- if (i != 0 ) {
208- entryPointsObject.addBefore(generator.createComma(), entryPointsObject.lastChild)
209- }
210- val values = generator.createValue<JsonArray >(" []" )
211- for (j in entryPointCategory.value.indices) {
212- if (j != 0 ) {
213- values.addBefore(generator.createComma(), values.lastChild)
214- }
215- val entryPointReference = entryPointCategory.value[j].computeReference(project)
216- val value = generator.createStringLiteral(entryPointReference)
217- values.addBefore(value, values.lastChild)
218- }
219- val key = StringUtil .escapeStringCharacters(entryPointCategory.key)
220- val prop = generator.createProperty(key, " []" )
221- prop.value?.replace(values)
222- entryPointsObject.addBefore(prop, entryPointsObject.lastChild)
223- }
224- }
225-
226- ReformatCodeProcessor (project, jsonFile, null , false ).run ()
94+ val packageName =
95+ " ${buildSystemProps.groupId.toPackageName()} .${modId.toPackageName()} .mixin"
96+ assets.addTemplateProperties(
97+ " MIXINS" to " true" ,
98+ " MIXIN_PACKAGE_NAME" to packageName,
99+ )
100+ val mixinsJsonFile = " src/main/resources/$modId .mixins.json"
101+ assets.addTemplates(project, mixinsJsonFile to FABRIC_MIXINS_JSON_TEMPLATE )
227102 }
228- }
229-
230- private fun createEntryPoints (project : Project ) {
231- val root = VfsUtil .findFile(Path .of(context.projectFileDirectory), true ) ? : return
232- val psiManager = PsiManager .getInstance(project)
233103
234- val generatedClasses = mutableSetOf<PsiClass >()
235-
236- for (entryPoint in entryPoints) {
237- // find the class, and create it if it doesn't exist
238- val clazz = JavaPsiFacade .getInstance(project).findClass(
239- entryPoint.className,
240- GlobalSearchScope .projectScope(project),
241- ) ? : run {
242- val packageName = entryPoint.className.substringBeforeLast(' .' , missingDelimiterValue = " " )
243- val className = entryPoint.className.substringAfterLast(' .' )
104+ assets.addLicense(project)
244105
245- val dir = VfsUtil .createDirectoryIfMissing(root, " src/main/java/${packageName.replace(' .' , ' /' )} " )
246- val psiDir = psiManager.findDirectory(dir) ? : return @run null
247- try {
248- JavaDirectoryService .getInstance().createClass(psiDir, className)
249- } catch (e: IncorrectOperationException ) {
250- invokeLater {
251- val message = MCDevBundle .message(
252- " intention.error.cannot.create.class.message" ,
253- className,
254- e.localizedMessage,
255- )
256- Messages .showErrorDialog(
257- project,
258- message,
259- MCDevBundle .message(" intention.error.cannot.create.class.title" ),
260- )
261- }
262- return
263- }
264- } ? : continue
106+ assets.addAssets(
107+ GeneratorEmptyDirectory (" src/main/java" ),
108+ GeneratorEmptyDirectory (" src/main/resources" ),
109+ )
265110
266- clazz.containingFile.runWriteAction {
267- clazz.addImplements(entryPoint.interfaceName)
111+ assets.addTemplates(project, " src/main/resources/fabric.mod.json" to FABRIC_MOD_JSON_TEMPLATE )
268112
269- val methodsToImplement = OverrideImplementUtil .getMethodsToOverrideImplement(clazz, true )
270- val methods = OverrideImplementUtil .overrideOrImplementMethodCandidates(clazz, methodsToImplement, true )
271- for (method in methods) {
272- clazz.addMethod(method)
273- }
274- }
113+ WriteAction .runAndWait<Throwable > {
114+ val dir = VfsUtil .createDirectoryIfMissing(
115+ LocalFileSystem .getInstance(),
116+ " ${assets.outputDirectory} /.gradle" ,
117+ )
118+ ? : throw IllegalStateException (" Unable to create .gradle directory" )
119+ val file = dir.findOrCreateChildData(this , MAGIC_DEFERRED_INIT_FILE )
275120
276- generatedClasses + = clazz
277- }
121+ val authors = data.getUserData(AuthorsStep .KEY ) ? : emptyList()
122+ val website = data.getUserData(WebsiteStep .KEY )
123+ val repo = data.getUserData(RepositoryStep .KEY )
278124
279- for (clazz in generatedClasses) {
280- ReformatCodeProcessor (project, clazz.containingFile, null , false ).run ()
281- EditorHelper .openInEditor(clazz)
282- }
283- }
125+ val packageName = " ${buildSystemProps.groupId.toPackageName()} .${modId.toPackageName()} "
126+ val mainClassName = " $packageName .${modName.toJavaClassName()} "
127+ val clientClassName = " $packageName .client.${modName.toJavaClassName()} Client"
284128
285- override fun perform ( project : Project ) {
286- super .perform(project)
287- val latch = CountDownLatch ( 1 )
288- assets.runWhenCreated(project) {
289- project.runWriteTaskInSmartMode {
290- try {
291- fixupFabricModJson(project)
292- createEntryPoints(project)
293- } finally {
294- latch.countDown()
295- }
296- }
129+ val entrypoints = listOf (
130+ " main, ${ EntryPoint . Type . CLASS .name} , $mainClassName , ${ FabricConstants . MOD_INITIALIZER } " ,
131+ " client, ${ EntryPoint . Type . CLASS .name} , $clientClassName , ${ FabricConstants . CLIENT_MOD_INITIALIZER } " ,
132+ )
133+ val fileContents = """
134+ ${authors.joinToString( " , " )}
135+ $website
136+ $repo
137+ ${entrypoints.joinToString( " ; " )}
138+ """ .trimIndent() // TODO: un-hardcode?
139+
140+ VfsUtil .saveText(file, fileContents)
297141 }
298- latch.await()
299142 }
300143}
301144
0 commit comments