Skip to content

Commit 7d03fb2

Browse files
committed
Merge branch '2022.1' into 2022.2
2 parents 5953139 + 91e691e commit 7d03fb2

32 files changed

+651
-271
lines changed

build.gradle.kts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
1717
import org.jlleitschuh.gradle.ktlint.tasks.BaseKtLintCheckTask
1818

1919
plugins {
20-
kotlin("jvm") version "1.7.10"
20+
kotlin("jvm") version "1.7.20"
2121
java
2222
mcdev
2323
groovy
@@ -85,6 +85,8 @@ dependencies {
8585
implementation(libs.mappingIo)
8686
implementation(libs.bundles.asm)
8787

88+
implementation(libs.bundles.fuel)
89+
8890
jflex(libs.jflex.lib)
8991
jflexSkeleton(libs.jflex.skeleton) {
9092
artifact {

gradle/libs.versions.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
[versions]
2-
coroutines = "1.6.3"
2+
coroutines = "1.6.4"
33
junit = "5.9.0"
44
junit-platform = "1.9.0"
55
asm = "9.3"
6+
fuel = "2.3.1"
67

78
[libraries]
89
coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
@@ -26,6 +27,9 @@ asm = { module = "org.ow2.asm:asm", version.ref = "asm" }
2627
asm-tree = { module = "org.ow2.asm:asm-tree", version.ref = "asm" }
2728
asm-analysis = { module = "org.ow2.asm:asm-analysis", version.ref = "asm" }
2829

30+
fuel = { module = "com.github.kittinunf.fuel:fuel", version.ref = "fuel" }
31+
fuel-coroutines = { module = "com.github.kittinunf.fuel:fuel-coroutines", version.ref = "fuel" }
32+
2933
# Testing
3034
test-mockJdk = "org.jetbrains.idea:mock-jdk:1.7-4d76c50"
3135
test-mixin = "org.spongepowered:mixin:0.8.5"
@@ -39,3 +43,4 @@ junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher
3943
[bundles]
4044
coroutines = ["coroutines-core", "coroutines-jdk8", "coroutines-swing"]
4145
asm = ["asm", "asm-tree", "asm-analysis"]
46+
fuel = ["fuel", "fuel-coroutines"]

src/main/grammars/AwParser.bnf

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,20 +88,15 @@ member_name ::= NAME_ELEMENT {
8888
]
8989
}
9090

91-
method_desc ::= OPEN_PAREN argument* CLOSE_PAREN return_value
91+
method_desc ::= OPEN_PAREN desc_element* CLOSE_PAREN desc_element
9292

93-
field_desc ::= argument
93+
field_desc ::= desc_element
9494

95-
argument ::= PRIMITIVE | CLASS_VALUE {
95+
desc_element ::= PRIMITIVE | CLASS_VALUE {
96+
mixin= "com.demonwav.mcdev.platform.mcp.aw.psi.mixins.impl.AwDescElementImplMixin"
97+
implements= "com.demonwav.mcdev.platform.mcp.aw.psi.mixins.AwDescElementMixin"
9698
methods=[
9799
primitive="PRIMITIVE"
98100
classValue="CLASS_VALUE"
99101
]
100-
}
101-
102-
return_value ::= PRIMITIVE | CLASS_VALUE {
103-
methods=[
104-
primitive="PRIMITIVE"
105-
classValue="CLASS_VALUE"
106-
]
107-
}
102+
}

src/main/kotlin/creator/PlatformVersion.kt

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,39 @@
1111
package com.demonwav.mcdev.creator
1212

1313
import com.demonwav.mcdev.platform.PlatformType
14-
import com.demonwav.mcdev.util.ProxyHttpConnectionFactory
14+
import com.demonwav.mcdev.update.PluginUtil
1515
import com.demonwav.mcdev.util.fromJson
16+
import com.github.kittinunf.fuel.core.FuelManager
17+
import com.github.kittinunf.fuel.core.requests.suspendable
18+
import com.github.kittinunf.fuel.coroutines.awaitString
1619
import com.google.gson.Gson
1720
import com.intellij.openapi.diagnostic.Attachment
1821
import com.intellij.openapi.diagnostic.Logger
22+
import com.intellij.util.proxy.CommonProxy
1923
import java.io.IOException
24+
import java.net.Proxy
25+
import java.net.URI
2026
import javax.swing.JComboBox
27+
import kotlin.reflect.KClass
2128

22-
private const val cloudflareBaseUrl = "https://minecraftdev.org/versions/"
23-
private const val githubBaseUrl = "https://raw.githubusercontent.com/minecraft-dev/minecraftdev.org/master/versions/"
29+
private const val CLOUDFLARE_BASE_URL = "https://minecraftdev.org/versions/"
30+
private const val GITHUB_BASE_URL = "https://raw.githubusercontent.com/minecraft-dev/minecraftdev.org/master/versions/"
2431

2532
val PLATFORM_VERSION_LOGGER = Logger.getInstance("MDev.PlatformVersion")
2633

27-
fun getVersionSelector(type: PlatformType): PlatformVersion {
34+
suspend fun getVersionSelector(type: PlatformType): PlatformVersion {
2835
val versionJson = type.versionJson ?: throw UnsupportedOperationException("Incorrect platform type: $type")
2936
return getVersionJson(versionJson)
3037
}
3138

32-
inline fun <reified T : Any> getVersionJson(path: String): T {
39+
suspend inline fun <reified T : Any> getVersionJson(path: String): T {
40+
return getVersionJson(path, T::class)
41+
}
42+
43+
suspend fun <T : Any> getVersionJson(path: String, type: KClass<T>): T {
3344
val text = getText(path)
3445
try {
35-
return Gson().fromJson(text)
46+
return Gson().fromJson(text, type)
3647
} catch (e: Exception) {
3748
val attachment = Attachment("JSON Document", text)
3849
attachment.isIncluded = true
@@ -41,32 +52,45 @@ inline fun <reified T : Any> getVersionJson(path: String): T {
4152
}
4253
}
4354

44-
fun getText(path: String): String {
55+
suspend fun getText(path: String): String {
4556
return try {
4657
// attempt cloudflare
47-
doCall(cloudflareBaseUrl + path)
58+
doCall(CLOUDFLARE_BASE_URL + path)
4859
} catch (e: IOException) {
49-
PLATFORM_VERSION_LOGGER.warn("Failed to reach cloudflare URL ${cloudflareBaseUrl + path}", e)
60+
PLATFORM_VERSION_LOGGER.warn("Failed to reach cloudflare URL ${CLOUDFLARE_BASE_URL + path}", e)
5061
// if that fails, attempt github
5162
try {
52-
doCall(githubBaseUrl + path)
63+
doCall(GITHUB_BASE_URL + path)
5364
} catch (e: IOException) {
54-
PLATFORM_VERSION_LOGGER.warn("Failed to reach fallback GitHub URL ${githubBaseUrl + path}", e)
65+
PLATFORM_VERSION_LOGGER.warn("Failed to reach fallback GitHub URL ${GITHUB_BASE_URL + path}", e)
5566
throw e
5667
}
5768
}
5869
}
5970

60-
private fun doCall(urlText: String): String {
61-
val connection = ProxyHttpConnectionFactory.openHttpConnection(urlText)
71+
private suspend fun doCall(urlText: String): String {
72+
val manager = FuelManager()
73+
manager.proxy = selectProxy(urlText)
74+
75+
return manager.get(urlText)
76+
.header("User-Agent", "github_org/minecraft-dev/${PluginUtil.pluginVersion}")
77+
.header("Accepts", "application/json")
78+
.suspendable()
79+
.awaitString()
80+
}
6281

63-
connection.setRequestProperty(
64-
"User-Agent",
65-
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " +
66-
"Chrome/72.0.3626.121 Safari/537.36"
67-
)
82+
fun selectProxy(urlText: String): Proxy? {
83+
val uri = URI(urlText)
84+
val url = uri.toURL()
6885

69-
return connection.inputStream.use { stream -> stream.reader().use { it.readText() } }
86+
val proxies = CommonProxy.getInstance().select(uri)
87+
for (proxy in proxies) {
88+
try {
89+
url.openConnection(proxy)
90+
return proxy
91+
} catch (_: IOException) {}
92+
}
93+
return null
7094
}
7195

7296
data class PlatformVersion(var versions: List<String>, var selectedIndex: Int) {

src/main/kotlin/creator/buildsystem/maven/maven-steps.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import java.nio.file.Path
4040
import java.nio.file.StandardOpenOption.CREATE
4141
import java.nio.file.StandardOpenOption.TRUNCATE_EXISTING
4242
import java.nio.file.StandardOpenOption.WRITE
43+
import kotlinx.coroutines.runBlocking
4344
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel
4445
import org.jetbrains.idea.maven.execution.MavenRunConfigurationType
4546
import org.jetbrains.idea.maven.execution.MavenRunnerParameters
@@ -103,7 +104,9 @@ class BasicMavenStep(
103104

104105
companion object {
105106
val pluginVersions by lazy {
106-
getVersionJson<Map<String, String>>("maven.json")
107+
runBlocking {
108+
getVersionJson<Map<String, String>>("maven.json")
109+
}
107110
}
108111

109112
private val defaultParts = listOf(setupDirs(), setupCore(), setupName(), setupInfo(), setupDependencies())

src/main/kotlin/insight/ListenerLineMarkerProvider.kt

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,19 @@ class ListenerLineMarkerProvider : LineMarkerProviderDescriptor() {
4141
return null
4242
}
4343

44-
val identifier = element.toUElementOfType<UIdentifier>() ?: return null
45-
if (identifier.uastParent !is UMethod || identifier.uastEventListener == null) {
46-
return null
44+
try {
45+
val identifier = element.toUElementOfType<UIdentifier>() ?: return null
46+
if (identifier.uastParent !is UMethod || identifier.uastEventListener == null) {
47+
return null
48+
}
49+
} catch (e: Exception) {
50+
// Kotlin plugin is buggy and can throw exceptions here
51+
// We do the check like this because we don't actually have this class on the classpath
52+
if (e.javaClass.name == "org.jetbrains.kotlin.idea.caches.resolve.KotlinIdeaResolutionException") {
53+
return null
54+
}
55+
// Don't swallow unexpected errors
56+
throw e
4757
}
4858

4959
// By this point, we can guarantee that the action of "go to declaration" will work

src/main/kotlin/inspection/IsCancelled.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class IsCancelled(
2424
this.buildFix = object : InspectionGadgetsFix() {
2525
override fun doFix(project: Project, descriptor: ProblemDescriptor) = fix(descriptor)
2626
override fun getName() = "Simplify"
27-
override fun getFamilyName() = "Useless IsCancelled Check"
27+
override fun getFamilyName() = "Useless isCancelled check"
2828
}
2929
}
3030
}

src/main/kotlin/inspection/IsCancelledInspection.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import org.jetbrains.annotations.Nls
2121

2222
class IsCancelledInspection : BaseInspection() {
2323
@Nls
24-
override fun getDisplayName() = "Useless event is cancelled check"
24+
override fun getDisplayName() = "Useless event isCancelled check"
2525

2626
override fun getStaticDescription(): String = "Reports useless event cancellation checks"
2727

src/main/kotlin/platform/architectury/creator/ArchitecturyProjectSettingsWizard.kt

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ import com.demonwav.mcdev.platform.architectury.version.FabricVersion
2222
import com.demonwav.mcdev.platform.forge.version.ForgeVersion
2323
import com.demonwav.mcdev.util.License
2424
import com.demonwav.mcdev.util.SemanticVersion
25+
import com.demonwav.mcdev.util.asyncIO
2526
import com.demonwav.mcdev.util.modUpdateStep
27+
import com.intellij.openapi.diagnostic.Logger
2628
import com.intellij.ui.CollectionComboBoxModel
2729
import com.intellij.ui.EnumComboBoxModel
2830
import java.awt.event.ActionListener
@@ -37,7 +39,7 @@ import kotlin.math.min
3739
import kotlinx.coroutines.CoroutineScope
3840
import kotlinx.coroutines.Dispatchers
3941
import kotlinx.coroutines.Job
40-
import kotlinx.coroutines.async
42+
import kotlinx.coroutines.awaitAll
4143
import kotlinx.coroutines.coroutineScope
4244
import kotlinx.coroutines.launch
4345
import kotlinx.coroutines.swing.Swing
@@ -234,6 +236,7 @@ class ArchitecturyProjectSettingsWizard(private val creator: MinecraftProjectCre
234236
updateMcForm(data)
235237
}
236238
} catch (e: Exception) {
239+
LOGGER.error("Failed to update versions form", e)
237240
error()
238241
}
239242

@@ -250,9 +253,9 @@ class ArchitecturyProjectSettingsWizard(private val creator: MinecraftProjectCre
250253
}
251254

252255
private suspend fun downloadVersions() = coroutineScope {
253-
val fabricVersionJob = async(Dispatchers.IO) { FabricVersion.downloadData() }
254-
val forgeVersionJob = async(Dispatchers.IO) { ForgeVersion.downloadData() }
255-
val architecturyApiVersionJob = async(Dispatchers.IO) { ArchitecturyVersion.downloadData() }
256+
val fabricVersionJob = asyncIO { FabricVersion.downloadData() }
257+
val forgeVersionJob = asyncIO { ForgeVersion.downloadData() }
258+
val architecturyApiVersionJob = asyncIO { ArchitecturyVersion.downloadData() }
256259

257260
versions = ArchitecturyVersions(
258261
fabricVersionJob.await() ?: return@coroutineScope,
@@ -262,29 +265,42 @@ class ArchitecturyProjectSettingsWizard(private val creator: MinecraftProjectCre
262265
}
263266

264267
private suspend fun updateForm(): Data? = coroutineScope {
265-
val vers = versions ?: return@coroutineScope null
268+
try {
269+
val vers = versions ?: return@coroutineScope null
266270

267-
val selectedVersion = version ?: vers.forgeVersion.sortedMcVersions.firstOrNull() ?: return@coroutineScope null
271+
val selectedVersion = version ?: vers.forgeVersion.sortedMcVersions.firstOrNull()
272+
?: return@coroutineScope null
268273

269-
val fabricVersionsJob = async(Dispatchers.IO) { vers.fabricVersion.getFabricVersions(selectedVersion) }
270-
val forgeVersionsJob = async(Dispatchers.IO) { vers.forgeVersion.getForgeVersions(selectedVersion) }
271-
val fabricApiVersionsJob = async(Dispatchers.IO) { vers.fabricVersion.getFabricApiVersions(selectedVersion) }
272-
val architecturyApiVersionsJob = async(Dispatchers.IO) {
273-
vers.architecturyVersion.getArchitecturyVersions(
274-
selectedVersion
275-
)
276-
}
274+
val fabricVersionsJob = asyncIO { vers.fabricVersion.getFabricVersions(selectedVersion) }
275+
val forgeVersionsJob = asyncIO { vers.forgeVersion.getForgeVersions(selectedVersion) }
276+
val fabricApiVersionsJob = asyncIO { vers.fabricVersion.getFabricApiVersions(selectedVersion) }
277+
val architecturyApiVersionsJob = asyncIO {
278+
vers.architecturyVersion.getArchitecturyVersions(selectedVersion)
279+
}
277280

278-
val fabricVersions = fabricVersionsJob.await()
279-
val forgeVersions = forgeVersionsJob.await()
280-
val fabricApiVersions = fabricApiVersionsJob.await()
281-
val architecturyApiVersions = architecturyApiVersionsJob.await()
281+
// awaitAll is better than calling .await() individually
282+
val (
283+
fabricVersions,
284+
forgeVersions,
285+
fabricApiVersions,
286+
architecturyApiVersions,
287+
) = listOf(
288+
fabricVersionsJob,
289+
forgeVersionsJob,
290+
fabricApiVersionsJob,
291+
architecturyApiVersionsJob
292+
).awaitAll()
282293

283-
val data = Data(0, fabricVersions, 0, forgeVersions, 0, fabricApiVersions, 0, architecturyApiVersions, 0)
294+
val data = Data(0, fabricVersions, 0, forgeVersions, 0, fabricApiVersions, 0, architecturyApiVersions, 0)
284295

285-
mcVersionUpdate(data)
296+
mcVersionUpdate(data)
286297

287-
return@coroutineScope data
298+
return@coroutineScope data
299+
} catch (e: Exception) {
300+
// log error manually - something is weird about intellij & coroutine exception handling
301+
LOGGER.error("Error while updating Architectury form version fields", e)
302+
return@coroutineScope null
303+
}
288304
}
289305

290306
private fun updateMcForm(data: Data) {
@@ -293,9 +309,16 @@ class ArchitecturyProjectSettingsWizard(private val creator: MinecraftProjectCre
293309
minecraftVersionBox.removeActionListener(minecraftBoxActionListener)
294310
minecraftVersionBox.removeAllItems()
295311

296-
minecraftVersionBox.model = CollectionComboBoxModel(
297-
vers.forgeVersion.sortedMcVersions.filter { it >= SemanticVersion.release(1, 16) }
298-
)
312+
// make copy, so the next 2 operations don't mess up the map
313+
val mcVersions = vers.architecturyVersion.versions.keys.toCollection(LinkedHashSet())
314+
mcVersions.retainAll(vers.forgeVersion.sortedMcVersions.toSet())
315+
// Fabric also targets preview versions which aren't semver
316+
// The other option would be to try to parse all of them and catching any exceptions
317+
// But exceptions are slow, so this should be more efficient
318+
val fabricMcVersions = vers.fabricVersion.versions.minecraftVersions.mapTo(HashSet()) { it.name }
319+
mcVersions.retainAll { fabricMcVersions.contains(it.toString()) }
320+
321+
minecraftVersionBox.model = CollectionComboBoxModel(mcVersions.sortedDescending())
299322
minecraftVersionBox.selectedIndex = data.mcSelectedIndex
300323
minecraftVersionBox.addActionListener(minecraftBoxActionListener)
301324
}
@@ -311,4 +334,8 @@ class ArchitecturyProjectSettingsWizard(private val creator: MinecraftProjectCre
311334
val architecturyApiVersions: List<SemanticVersion>,
312335
val architecturyApiSelectedIndex: Int
313336
)
337+
338+
companion object {
339+
val LOGGER = Logger.getInstance(ArchitecturyProjectSettingsWizard::class.java)
340+
}
314341
}

0 commit comments

Comments
 (0)