Skip to content

Commit 8bb8425

Browse files
committed
Merge branch '2024.2' into 2024.3
2 parents 4cd5d91 + 53c2b76 commit 8bb8425

File tree

16 files changed

+855
-88
lines changed

16 files changed

+855
-88
lines changed

.github/workflows/test.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,9 @@ jobs:
3838
echo -e '\norg.gradle.jvmargs=-Xmx4G\n' >> ~/.gradle/gradle.properties
3939
- name: Build
4040
run: ./gradlew build --stacktrace
41+
- name: Upload test reports
42+
if: always()
43+
uses: actions/upload-artifact@v4
44+
with:
45+
name: test-reports-${{ matrix.os }}
46+
path: build/reports

changelog.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
# Minecraft Development for IntelliJ
22

3+
## [1.8.5]
4+
5+
### Added
6+
7+
- Support for the 2025.2 EAP
8+
9+
### Changed
10+
11+
- Demote a couple of mixin inspections from error to warning
12+
- Allow handler methods to be static even when not required, except for `@Inject` on stock mixin
13+
- Allow `CallbackInfoReturnable.cancel()` in MixinCancellableInspection
14+
- Check bases for `CIR.cancel()`
15+
- Allow `.aw` as alternative access widener file extension
16+
17+
### Fixed
18+
19+
- [#2148](https://github.com/minecraft-dev/MinecraftDev/issues/2148) Allow assignment to `@Final` fields in class initializer blocks
20+
- [#2468](https://github.com/minecraft-dev/MinecraftDev/issues/2468) Fix entrypoint checks on non-ending parts of entrypoint references, and handle escapes in entrypoint reference strings
21+
322
## [1.8.4]
423

524
### Added

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ org.gradle.jvmargs=-Xmx1g
2323

2424
ideaVersionName = 2024.3
2525

26-
coreVersion = 1.8.4
26+
coreVersion = 1.8.5
2727

2828
# Silences a build-time warning because we are bundling our own kotlin library
2929
kotlin.stdlib.default.dependency = false

readme.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ Minecraft Development for IntelliJ
2323
<td align="left">2025.1</td>
2424
<td align="left"><a href="https://ci.mcdev.io/viewType.html?buildTypeId=MinecraftDev_Nightly_20251"><img src="https://ci.mcdev.io/app/rest/builds/buildType:(id:MinecraftDev_Nightly_20251)/statusIcon.svg" alt="2025.1 Nightly Status" /></a></td>
2525
</tr>
26+
<tr>
27+
<td align="left">2025.2</td>
28+
<td align="left"><a href="https://ci.mcdev.io/viewType.html?buildTypeId=MinecraftDev_Nightly_20252"><img src="https://ci.mcdev.io/app/rest/builds/buildType:(id:MinecraftDev_Nightly_20252)/statusIcon.svg" alt="2025.2 Nightly Status" /></a></td>
29+
</tr>
2630
<tr>
2731
<td align="right"><b>OS Tests</b></td>
2832
<td align="left" colspan="2">
@@ -31,7 +35,7 @@ Minecraft Development for IntelliJ
3135
</tr>
3236
</table>
3337

34-
Info and Documentation [![Current Release](https://img.shields.io/badge/release-1.8.4-orange.svg?style=flat-square)](https://plugins.jetbrains.com/plugin/8327)
38+
Info and Documentation [![Current Release](https://img.shields.io/badge/release-1.8.5-orange.svg?style=flat-square)](https://plugins.jetbrains.com/plugin/8327)
3539
----------------------
3640

3741
<a href="https://discord.gg/j6UNcfr"><img src="https://i.imgur.com/JXu9C1G.png" height="48px"></img></a>

src/main/kotlin/facet/MinecraftFacetDetector.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import com.intellij.facet.FacetManager
3232
import com.intellij.facet.impl.ui.libraries.LibrariesValidatorContextImpl
3333
import com.intellij.framework.library.LibraryVersionProperties
3434
import com.intellij.openapi.application.EDT
35+
import com.intellij.openapi.application.readAction
3536
import com.intellij.openapi.components.Service
3637
import com.intellij.openapi.components.service
3738
import com.intellij.openapi.module.Module
@@ -132,8 +133,14 @@ class MinecraftFacetDetector : ProjectActivity {
132133
}
133134
}
134135

135-
private fun checkNoFacet(module: Module) {
136-
val platforms = autoDetectTypes(module).ifEmpty { return }
136+
private suspend fun checkNoFacet(module: Module) {
137+
val platforms = readAction {
138+
if (!module.isDisposed) {
139+
autoDetectTypes(module)
140+
} else {
141+
emptyList()
142+
}
143+
}.ifEmpty { return }
137144

138145
runWriteTaskLater {
139146
// Only add the new facet if there isn't a Minecraft facet already - double check here since this

src/main/kotlin/platform/fabric/inspection/FabricEntrypointsInspection.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ class FabricEntrypointsInspection : LocalInspectionTool() {
7979
)
8080
}
8181

82+
if (!reference.isFinalPart) {
83+
continue
84+
}
85+
8286
val element = resolved.singleOrNull()?.element
8387
when {
8488
element is PsiClass && !literal.text.contains("::") -> {

src/main/kotlin/platform/fabric/reference/EntryPointReference.kt

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import com.intellij.psi.PsiClassType
3535
import com.intellij.psi.PsiElement
3636
import com.intellij.psi.PsiElementResolveResult
3737
import com.intellij.psi.PsiField
38+
import com.intellij.psi.PsiLanguageInjectionHost
3839
import com.intellij.psi.PsiMethod
3940
import com.intellij.psi.PsiModifier
4041
import com.intellij.psi.PsiPolyVariantReference
@@ -51,12 +52,17 @@ import com.intellij.util.ProcessingContext
5152

5253
object EntryPointReference : PsiReferenceProvider() {
5354
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> {
54-
if (element !is JsonStringLiteral) {
55+
if (element !is JsonStringLiteral || element !is PsiLanguageInjectionHost) {
5556
return PsiReference.EMPTY_ARRAY
5657
}
5758
val manipulator = element.manipulator ?: return PsiReference.EMPTY_ARRAY
5859
val range = manipulator.getRangeInElement(element)
59-
val text = element.text.substring(range.startOffset, range.endOffset)
60+
val escaper = element.createLiteralTextEscaper()
61+
val text = buildString {
62+
if (!escaper.decode(range, this)) {
63+
return PsiReference.EMPTY_ARRAY
64+
}
65+
}
6066
val memberParts = text.split("::", limit = 2)
6167
val clazzParts = memberParts[0].split("$", limit = 0)
6268
val references = mutableListOf<Reference>()
@@ -68,7 +74,10 @@ object EntryPointReference : PsiReferenceProvider() {
6874
references.add(
6975
Reference(
7076
element,
71-
range.cutOut(TextRange.from(cursor, clazzPart.length)),
77+
TextRange.create(
78+
escaper.getOffsetInHost(cursor, range),
79+
escaper.getOffsetInHost(cursor + clazzPart.length, range)
80+
),
7281
innerClassDepth,
7382
false,
7483
),
@@ -80,12 +89,16 @@ object EntryPointReference : PsiReferenceProvider() {
8089
references.add(
8190
Reference(
8291
element,
83-
range.cutOut(TextRange.from(cursor, memberParts[1].length)),
92+
TextRange.create(
93+
escaper.getOffsetInHost(cursor, range),
94+
escaper.getOffsetInHost(cursor + memberParts[1].length, range),
95+
),
8496
innerClassDepth,
8597
true,
8698
),
8799
)
88100
}
101+
references.lastOrNull()?.isFinalPart = true
89102
return references.toTypedArray()
90103
}
91104

@@ -167,6 +180,9 @@ object EntryPointReference : PsiReferenceProvider() {
167180
PsiPolyVariantReference,
168181
InspectionReference {
169182

183+
var isFinalPart = false
184+
internal set
185+
170186
override val description = "entry point '%s'"
171187
override val unresolved = resolve() == null
172188

src/main/kotlin/platform/mixin/handlers/desugar/DesugarUtil.kt

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,16 @@ import com.intellij.openapi.util.Key
2626
import com.intellij.psi.JavaRecursiveElementWalkingVisitor
2727
import com.intellij.psi.PsiClass
2828
import com.intellij.psi.PsiElement
29-
import com.intellij.psi.PsiFile
29+
import com.intellij.psi.PsiJavaFile
3030
import com.intellij.psi.util.PsiTreeUtil
3131
import com.intellij.psi.util.parents
32+
import org.jetbrains.annotations.VisibleForTesting
3233

3334
object DesugarUtil {
3435
private val ORIGINAL_ELEMENT_KEY = Key.create<PsiElement>("mcdev.desugar.originalElement")
3536

36-
private val DESUGARERS = arrayOf<Desugarer>(
37+
private val DESUGARERS = arrayOf(
38+
RemoveVarArgsDesugarer,
3739
FieldAssignmentDesugarer,
3840
)
3941

@@ -45,19 +47,34 @@ object DesugarUtil {
4547
desugared.putCopyableUserData(ORIGINAL_ELEMENT_KEY, original)
4648
}
4749

48-
fun desugar(project: Project, clazz: PsiClass): PsiClass {
49-
return clazz.cached {
50-
val desugaredFile = clazz.containingFile.copy() as PsiFile
51-
val desugaredClass = PsiTreeUtil.findSameElementInCopy(clazz, desugaredFile)
52-
setOriginalRecursive(desugaredClass, clazz)
50+
fun getOriginalToDesugaredMap(desugared: PsiElement): Map<PsiElement, List<PsiElement>> {
51+
val desugaredFile = desugared.containingFile ?: return emptyMap()
52+
return desugaredFile.cached {
53+
val result = mutableMapOf<PsiElement, MutableList<PsiElement>>()
54+
PsiTreeUtil.processElements(desugaredFile) { desugaredElement ->
55+
desugaredElement.getCopyableUserData(ORIGINAL_ELEMENT_KEY)?.let { original ->
56+
result.getOrPut(original) { mutableListOf() } += desugaredElement
57+
}
58+
true
59+
}
60+
result
61+
}
62+
}
63+
64+
fun desugar(project: Project, clazz: PsiClass): PsiClass? {
65+
val file = clazz.containingFile as? PsiJavaFile ?: return null
66+
return file.cached {
67+
val desugaredFile = file.copy() as PsiJavaFile
68+
setOriginalRecursive(desugaredFile, file)
5369
for (desugarer in DESUGARERS) {
54-
desugarer.desugar(project, desugaredClass)
70+
desugarer.desugar(project, desugaredFile)
5571
}
56-
desugaredClass
72+
getOriginalToDesugaredMap(desugaredFile)[clazz]?.filterIsInstance<PsiClass>()?.firstOrNull()
5773
}
5874
}
5975

60-
private fun setOriginalRecursive(desugared: PsiElement, original: PsiElement) {
76+
@VisibleForTesting
77+
fun setOriginalRecursive(desugared: PsiElement, original: PsiElement) {
6178
val desugaredElements = mutableListOf<PsiElement>()
6279
desugared.accept(object : JavaRecursiveElementWalkingVisitor() {
6380
override fun visitElement(element: PsiElement) {
@@ -78,17 +95,4 @@ object DesugarUtil {
7895
setOriginalElement(desugaredElement, originalElement)
7996
}
8097
}
81-
82-
fun getOriginalToDesugaredMap(desugared: PsiElement): Map<PsiElement, List<PsiElement>> {
83-
val result = mutableMapOf<PsiElement, MutableList<PsiElement>>()
84-
desugared.accept(object : JavaRecursiveElementWalkingVisitor() {
85-
override fun visitElement(element: PsiElement) {
86-
super.visitElement(element)
87-
getOriginalElement(element)?.let { original ->
88-
result.getOrPut(original) { mutableListOf() } += desugared
89-
}
90-
}
91-
})
92-
return result
93-
}
9498
}

src/main/kotlin/platform/mixin/handlers/desugar/Desugarer.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,15 @@ package com.demonwav.mcdev.platform.mixin.handlers.desugar
2222

2323
import com.intellij.openapi.project.Project
2424
import com.intellij.psi.PsiClass
25+
import com.intellij.psi.PsiJavaFile
26+
import com.intellij.psi.util.childrenOfType
2527

26-
interface Desugarer {
27-
fun desugar(project: Project, clazz: PsiClass)
28+
abstract class Desugarer {
29+
abstract fun desugar(project: Project, file: PsiJavaFile)
30+
31+
companion object {
32+
@JvmStatic
33+
protected val PsiJavaFile.allClasses: List<PsiClass>
34+
get() = this.childrenOfType<PsiClass>()
35+
}
2836
}

0 commit comments

Comments
 (0)