Skip to content

Commit 54ffec2

Browse files
committed
Merge branch '2025.2' into 2025.3
2 parents 0b0486d + 66f57a6 commit 54ffec2

6 files changed

Lines changed: 99 additions & 10 deletions

File tree

changelog.md

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

3+
## [1.8.16]
4+
5+
### Added
6+
7+
- Added autocompletion for `@Desc` selector
8+
9+
### Fixed
10+
11+
- Fixed freeze of analysis in occasional classes caused by `TranslationIdentifier`
12+
313
## [1.8.15]
414

515
### 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 = 2025.3
2525

26-
coreVersion = 1.8.15
26+
coreVersion = 1.8.16
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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Minecraft Development for IntelliJ
3131
</tr>
3232
</table>
3333

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

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

src/main/kotlin/platform/mixin/reference/AbstractMethodReference.kt

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
package com.demonwav.mcdev.platform.mixin.reference
2222

2323
import com.demonwav.mcdev.platform.mixin.handlers.MixinAnnotationHandler
24+
import com.demonwav.mcdev.platform.mixin.handlers.injectionPoint.InjectionPoint
2425
import com.demonwav.mcdev.platform.mixin.reference.target.TargetReference
2526
import com.demonwav.mcdev.platform.mixin.util.ClassAndMethodNode
2627
import com.demonwav.mcdev.platform.mixin.util.bytecode
@@ -39,6 +40,7 @@ import com.demonwav.mcdev.util.reference.completeToLiteral
3940
import com.demonwav.mcdev.util.toResolveResults
4041
import com.demonwav.mcdev.util.toTypedArray
4142
import com.intellij.codeInsight.completion.JavaLookupElementBuilder
43+
import com.intellij.codeInsight.completion.PrioritizedLookupElement
4244
import com.intellij.codeInsight.lookup.LookupElementBuilder
4345
import com.intellij.psi.PsiAnnotation
4446
import com.intellij.psi.PsiArrayInitializerMemberValue
@@ -193,7 +195,16 @@ abstract class AbstractMethodReference : PolyReferenceResolver(), MixinReference
193195
}
194196
}
195197

196-
return createLookup(context, methods.asSequence().map { ClassAndMethodNode(target, it) }, uniqueMethods)
198+
val dynamicSelectors = MixinSelectorParser.EP_NAME.extensionList.asSequence()
199+
.filterIsInstance<DynamicSelectorParser>()
200+
.map { "@${it.id}" }
201+
202+
return createLookup(
203+
context,
204+
methods.asSequence().map { ClassAndMethodNode(target, it) },
205+
uniqueMethods,
206+
dynamicSelectors
207+
)
197208
}
198209

199210
private fun collectVariants(context: PsiElement, targets: Collection<ClassNode>): Array<Any> {
@@ -227,13 +238,18 @@ abstract class AbstractMethodReference : PolyReferenceResolver(), MixinReference
227238
}
228239
}
229240

230-
return createLookup(context, allMethods.asSequence(), uniqueMethods)
241+
val dynamicSelectors = MixinSelectorParser.EP_NAME.extensionList.asSequence()
242+
.filterIsInstance<DynamicSelectorParser>()
243+
.map { "@${it.id}" }
244+
245+
return createLookup(context, allMethods.asSequence(), uniqueMethods, dynamicSelectors)
231246
}
232247

233248
private fun createLookup(
234249
context: PsiElement,
235250
methods: Sequence<ClassAndMethodNode>,
236251
uniqueMethods: Set<String>,
252+
dynamicSelectors: Sequence<String>
237253
): Array<Any> {
238254
return methods
239255
.map { m ->
@@ -256,8 +272,17 @@ abstract class AbstractMethodReference : PolyReferenceResolver(), MixinReference
256272
null,
257273
)
258274
.withPresentableText(m.method.name)
259-
addCompletionInfo(builder, context, targetMethodInfo)
260-
}.toTypedArray()
275+
PrioritizedLookupElement.withPriority(
276+
addCompletionInfo(builder, context, targetMethodInfo),
277+
1.0
278+
)
279+
}.plus(dynamicSelectors.map {
280+
PrioritizedLookupElement.withPriority(
281+
LookupElementBuilder.create(it).completeDynamicSelector(context),
282+
0.0
283+
)
284+
})
285+
.toTypedArray()
261286
}
262287

263288
open val requireDescriptor = false
@@ -269,4 +294,15 @@ abstract class AbstractMethodReference : PolyReferenceResolver(), MixinReference
269294
): LookupElementBuilder {
270295
return builder.completeToLiteral(context)
271296
}
297+
298+
private fun LookupElementBuilder.completeDynamicSelector(context: PsiElement): LookupElementBuilder {
299+
val id = lookupString.removePrefix("@")
300+
val parser = MixinSelectorParser.EP_NAME.extensionList.asSequence()
301+
.filterIsInstance<DynamicSelectorParser>()
302+
.firstOrNull { id in it.validIds } ?: return completeToLiteral(context)
303+
304+
return completeToLiteral(context) { editor, element ->
305+
parser.onCompleted(editor, element)
306+
}
307+
}
272308
}

src/main/kotlin/platform/mixin/reference/MixinSelectors.kt

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import com.demonwav.mcdev.util.constantStringValue
3636
import com.demonwav.mcdev.util.descriptor
3737
import com.demonwav.mcdev.util.findAnnotation
3838
import com.demonwav.mcdev.util.findContainingClass
39+
import com.demonwav.mcdev.util.findContainingModifierList
3940
import com.demonwav.mcdev.util.findField
4041
import com.demonwav.mcdev.util.findMethods
4142
import com.demonwav.mcdev.util.findQualifiedClass
@@ -45,6 +46,7 @@ import com.demonwav.mcdev.util.mapToArray
4546
import com.demonwav.mcdev.util.resolveClass
4647
import com.demonwav.mcdev.util.resolveType
4748
import com.demonwav.mcdev.util.resolveTypeArray
49+
import com.intellij.openapi.editor.Editor
4850
import com.intellij.openapi.extensions.ExtensionPointName
4951
import com.intellij.openapi.project.Project
5052
import com.intellij.openapi.util.RecursionManager
@@ -55,10 +57,14 @@ import com.intellij.psi.PsiCallExpression
5557
import com.intellij.psi.PsiClass
5658
import com.intellij.psi.PsiElement
5759
import com.intellij.psi.PsiField
60+
import com.intellij.psi.PsiLiteral
5861
import com.intellij.psi.PsiMember
5962
import com.intellij.psi.PsiMethod
63+
import com.intellij.psi.PsiModifierList
6064
import com.intellij.psi.PsiNameValuePair
6165
import com.intellij.psi.PsiTypes
66+
import com.intellij.psi.codeStyle.CodeStyleManager
67+
import com.intellij.psi.codeStyle.JavaCodeStyleManager
6268
import com.intellij.psi.search.GlobalSearchScope
6369
import com.intellij.psi.search.searches.AnnotatedMembersSearch
6470
import com.intellij.psi.search.searches.MethodReferencesSearch
@@ -418,7 +424,7 @@ private fun findNamespace(
418424

419425
private val DYNAMIC_SELECTOR_PATTERN = "(?i)^@([a-z]+(:[a-z]+)?)(\\((.*)\\))?$".toRegex()
420426

421-
abstract class DynamicSelectorParser(id: String, vararg aliases: String) : MixinSelectorParser {
427+
abstract class DynamicSelectorParser(val id: String, vararg aliases: String) : MixinSelectorParser {
422428
val validIds = aliases.toSet() + id
423429

424430
final override fun parse(value: String, context: PsiElement): MixinSelector? {
@@ -431,6 +437,9 @@ abstract class DynamicSelectorParser(id: String, vararg aliases: String) : Mixin
431437
}
432438

433439
abstract fun parseDynamic(args: String, context: PsiElement): MixinSelector?
440+
441+
open fun onCompleted(editor: Editor, reference: PsiLiteral) {
442+
}
434443
}
435444

436445
// @Desc
@@ -546,6 +555,32 @@ class DescSelectorParser : DynamicSelectorParser("Desc", "mixin:Desc") {
546555
}
547556
}
548557

558+
override fun onCompleted(editor: Editor, reference: PsiLiteral) {
559+
val modifierList = reference.findContainingModifierList() ?: return
560+
if (modifierList.hasAnnotation(DESC)) {
561+
return
562+
}
563+
564+
val project = reference.project
565+
566+
val descAnnotation = modifierList.addAfter(
567+
JavaPsiFacade.getElementFactory(project)
568+
.createAnnotationFromText("@${DESC}(\"\")", reference),
569+
null
570+
)
571+
572+
// add imports and reformat
573+
JavaCodeStyleManager.getInstance(project).shortenClassReferences(descAnnotation)
574+
JavaCodeStyleManager.getInstance(project).optimizeImports(modifierList.containingFile)
575+
val formattedModifierList = CodeStyleManager.getInstance(project).reformat(modifierList) as PsiModifierList
576+
577+
// move the caret to @Desc("<caret>")
578+
val formattedDescAnnotation = formattedModifierList.findAnnotation(DESC)
579+
?: return
580+
val descLiteral = formattedDescAnnotation.findDeclaredAttributeValue(null) ?: return
581+
editor.caretModel.moveToOffset(descLiteral.textRange.startOffset + 1)
582+
}
583+
549584
object Util {
550585
fun descSelectorFromAnnotation(descAnnotation: PsiAnnotation): DescSelector? {
551586
val explicitOwner = descAnnotation.findAttributeValue("owner")

src/main/kotlin/translations/identification/TranslationIdentifier.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import com.intellij.codeInsight.AnnotationUtil
3737
import com.intellij.codeInsight.completion.CompletionUtilCore
3838
import com.intellij.codeInspection.dataFlow.CommonDataflow
3939
import com.intellij.openapi.project.Project
40-
import com.intellij.openapi.util.RecursionManager
4140
import com.intellij.psi.CommonClassNames
4241
import com.intellij.psi.JavaPsiFacade
4342
import com.intellij.psi.PsiArrayType
@@ -58,6 +57,8 @@ import org.jetbrains.uast.getContainingUClass
5857
import org.jetbrains.uast.util.isNewArrayWithInitializer
5958

6059
object TranslationIdentifier {
60+
private val isComputingValueWithDataflow = ThreadLocal.withInitial { false }
61+
6162
fun identify(
6263
element: UExpression
6364
): TranslationInstance? {
@@ -89,8 +90,15 @@ object TranslationIdentifier {
8990

9091
val translationKey = when (val javaPsi = element.javaPsi) {
9192
is PsiExpression -> {
92-
RecursionManager.doPreventingRecursion(javaPsi, false) {
93-
CommonDataflow.computeValue(javaPsi) as? String
93+
if (isComputingValueWithDataflow.get()) {
94+
null
95+
} else {
96+
isComputingValueWithDataflow.set(true)
97+
try {
98+
CommonDataflow.computeValue(javaPsi) as? String
99+
} finally {
100+
isComputingValueWithDataflow.set(false)
101+
}
94102
}
95103
}
96104
else -> element.evaluateString()

0 commit comments

Comments
 (0)