20
20
21
21
package com.demonwav.mcdev.platform.fabric.creator
22
22
23
- import com.demonwav.mcdev.asset.MCDevBundle
24
23
import com.demonwav.mcdev.creator.JdkProjectSetupFinalizer
25
24
import com.demonwav.mcdev.creator.addLicense
26
25
import com.demonwav.mcdev.creator.addTemplates
@@ -43,69 +42,20 @@ import com.demonwav.mcdev.platform.fabric.util.FabricConstants
43
42
import com.demonwav.mcdev.platform.forge.inspections.sideonly.Side
44
43
import com.demonwav.mcdev.util.MinecraftTemplates.Companion.FABRIC_MIXINS_JSON_TEMPLATE
45
44
import 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
51
45
import com.demonwav.mcdev.util.toJavaClassName
52
46
import com.demonwav.mcdev.util.toPackageName
53
- import com.intellij.codeInsight.actions.ReformatCodeProcessor
54
- import com.intellij.codeInsight.generation.OverrideImplementUtil
55
47
import com.intellij.ide.starters.local.GeneratorEmptyDirectory
56
- import com.intellij.ide.util.EditorHelper
57
48
import 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
63
50
import com.intellij.openapi.project.Project
64
- import com.intellij.openapi.ui.Messages
65
51
import com.intellij.openapi.util.text.StringUtil
52
+ import com.intellij.openapi.vfs.LocalFileSystem
66
53
import 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
75
54
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"
84
56
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)"
109
59
110
60
override fun setupAssets (project : Project ) {
111
61
val buildSystemProps = findStep<BuildSystemPropertiesStep <* >>()
@@ -124,14 +74,6 @@ class FabricSmartModeFilesStep(parent: NewProjectWizardStep) : AbstractLongRunni
124
74
val apiVersion = data.getUserData(FabricVersionChainStep .API_VERSION_KEY )
125
75
val useMixins = data.getUserData(UseMixinsStep .KEY ) ? : false
126
76
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
-
135
77
assets.addTemplateProperties(
136
78
" ARTIFACT_ID" to buildSystemProps.artifactId,
137
79
" MOD_ID" to modId,
@@ -149,153 +91,54 @@ class FabricSmartModeFilesStep(parent: NewProjectWizardStep) : AbstractLongRunni
149
91
}
150
92
151
93
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 )
227
102
}
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)
233
103
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)
244
105
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
+ )
265
110
266
- clazz.containingFile.runWriteAction {
267
- clazz.addImplements(entryPoint.interfaceName)
111
+ assets.addTemplates(project, " src/main/resources/fabric.mod.json" to FABRIC_MOD_JSON_TEMPLATE )
268
112
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 )
275
120
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 )
278
124
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"
284
128
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)
297
141
}
298
- latch.await()
299
142
}
300
143
}
301
144
0 commit comments