Skip to content

Commit 5c6891e

Browse files
authored
Support for MixinExtras 0.5.0-beta.5 (#2431)
* Build: Bump MixinExtras Expressions. * Fix: Get ME Expressions string constants from the flows not the bytecode. Things like string concat expansion will result in nodes that weren't there originally. * Change: Allow `@Coerce` on `@WrapMethod` params. * New: Support `mixinextras` entry in mixin configs.
1 parent f3e34df commit 5c6891e

File tree

5 files changed

+53
-20
lines changed

5 files changed

+53
-20
lines changed

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ changelog-plugin = { module = "org.jetbrains.changelog:org.jetbrains.changelog.g
3131
coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "coroutines" }
3232

3333
mappingIo = "net.fabricmc:mapping-io:0.2.1"
34-
mixinExtras-expressions = "io.github.llamalad7:mixinextras-expressions:0.0.1"
34+
mixinExtras-expressions = "io.github.llamalad7:mixinextras-expressions:0.0.3"
3535

3636
# GrammarKit
3737
jflex-lib = "org.jetbrains.idea:jflex:1.7.0-b7f882a"

src/main/kotlin/platform/mixin/config/reference/ConfigProperty.kt

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@ package com.demonwav.mcdev.platform.mixin.config.reference
2323
import com.demonwav.mcdev.platform.mixin.util.MixinConstants.Classes.MIXIN_CONFIG
2424
import com.demonwav.mcdev.platform.mixin.util.MixinConstants.Classes.MIXIN_SERIALIZED_NAME
2525
import com.demonwav.mcdev.platform.mixin.util.MixinConstants.Classes.SERIALIZED_NAME
26+
import com.demonwav.mcdev.platform.mixin.util.MixinConstants.MixinExtras.MIXIN_EXTRAS_CONFIG
27+
import com.demonwav.mcdev.platform.mixin.util.MixinConstants.MixinExtras.MIXIN_EXTRAS_CONFIG_KEY
28+
import com.demonwav.mcdev.platform.mixin.util.MixinConstants.MixinExtras.MIXIN_EXTRAS_SERIALIZED_NAME
2629
import com.demonwav.mcdev.util.constantStringValue
27-
import com.demonwav.mcdev.util.findAnnotation
2830
import com.demonwav.mcdev.util.ifEmpty
2931
import com.demonwav.mcdev.util.reference.InspectionReference
32+
import com.demonwav.mcdev.util.toTypedArray
3033
import com.intellij.codeInsight.lookup.LookupElementBuilder
3134
import com.intellij.json.psi.JsonProperty
3235
import com.intellij.json.psi.JsonStringLiteral
@@ -48,18 +51,25 @@ object ConfigProperty : PsiReferenceProvider() {
4851
arrayOf(Reference(element as JsonStringLiteral))
4952

5053
fun resolveReference(element: JsonStringLiteral): PsiElement? {
54+
val name = element.value
55+
customSubConfigs[name]?.let {
56+
return JavaPsiFacade.getInstance(element.project).findClass(it, element.resolveScope)
57+
}
5158
val configClass = findConfigClass(element) ?: return null
5259
return findProperty(configClass, element.value)
5360
}
5461

5562
private fun collectVariants(context: PsiElement): Array<Any> {
5663
val configClass = findConfigClass(context) ?: return ArrayUtil.EMPTY_OBJECT_ARRAY
5764

58-
val list = ArrayList<LookupElementBuilder>()
65+
val list = mutableListOf<String>()
5966
forEachProperty(configClass) { _, name ->
60-
list.add(LookupElementBuilder.create(name))
67+
list.add(name)
68+
}
69+
if (configClass.qualifiedName == MIXIN_CONFIG) {
70+
list.addAll(customSubConfigs.keys)
6171
}
62-
return list.toArray()
72+
return list.asSequence().map { LookupElementBuilder.create(it) }.toTypedArray()
6373
}
6474

6575
private fun findProperty(configClass: PsiClass, name: String): PsiField? {
@@ -73,15 +83,8 @@ object ConfigProperty : PsiReferenceProvider() {
7383
}
7484

7585
private inline fun forEachProperty(configClass: PsiClass, func: (PsiField, String) -> Unit) {
76-
val mixinSerializedNameClass =
77-
JavaPsiFacade.getInstance(configClass.project).findClass(MIXIN_SERIALIZED_NAME, configClass.resolveScope)
78-
val serializedNameName = if (mixinSerializedNameClass != null) {
79-
MIXIN_SERIALIZED_NAME
80-
} else {
81-
SERIALIZED_NAME
82-
}
8386
for (field in configClass.fields) {
84-
val annotation = field.findAnnotation(serializedNameName)
87+
val annotation = field.annotations.find { it.qualifiedName in serializedNameAnnotations }
8588
val name = annotation?.findDeclaredAttributeValue(null)?.constantStringValue ?: continue
8689
func(field, name)
8790
}
@@ -107,6 +110,14 @@ object ConfigProperty : PsiReferenceProvider() {
107110

108111
// Walk to correct class
109112
var currentClass = mixinConfig
113+
114+
customSubConfigs[path.first()]?.let { newRoot ->
115+
path.removeFirst()
116+
currentClass =
117+
JavaPsiFacade.getInstance(context.project).findClass(newRoot, context.resolveScope)
118+
?: return null
119+
}
120+
110121
for (i in path.lastIndex downTo 0) {
111122
currentClass = (findProperty(currentClass, path[i])?.type as? PsiClassType)?.resolve() ?: return null
112123
}
@@ -127,4 +138,14 @@ object ConfigProperty : PsiReferenceProvider() {
127138
override fun getVariants() = collectVariants(element)
128139
override fun isReferenceTo(element: PsiElement) = element is PsiField && super.isReferenceTo(element)
129140
}
141+
142+
private val customSubConfigs = mapOf(
143+
MIXIN_EXTRAS_CONFIG_KEY to MIXIN_EXTRAS_CONFIG
144+
)
145+
146+
private val serializedNameAnnotations = setOf(
147+
SERIALIZED_NAME,
148+
MIXIN_SERIALIZED_NAME,
149+
MIXIN_EXTRAS_SERIALIZED_NAME
150+
)
130151
}

src/main/kotlin/platform/mixin/expression/MEExpressionCompletionUtil.kt

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -252,14 +252,21 @@ object MEExpressionCompletionUtil {
252252
handler to annotation
253253
} ?: return emptyList()
254254

255-
return handler.resolveTarget(handlerAnnotation).flatMap {
256-
(it as? MethodTargetMember)?.classAndMethod?.method?.instructions?.mapNotNull { insn ->
257-
if (insn is LdcInsnNode && insn.cst is String) {
258-
LookupElementBuilder.create(insn.cst)
259-
} else {
260-
null
255+
return handler.resolveTarget(handlerAnnotation).flatMap { member ->
256+
(member as? MethodTargetMember)?.classAndMethod
257+
?.let { (clazz, method) -> MEExpressionMatchUtil.getFlowMap(project, clazz, method) }
258+
?.values
259+
?.asSequence()
260+
?.filterNot { it.isComplex }
261+
?.map { it.insn }
262+
?.mapNotNull { insn ->
263+
if (insn is LdcInsnNode && insn.cst is String) {
264+
LookupElementBuilder.create(insn.cst)
265+
} else {
266+
null
267+
}
261268
}
262-
} ?: emptyList()
269+
.orEmpty()
263270
}
264271
}
265272

src/main/kotlin/platform/mixin/handlers/mixinextras/WrapMethodHandler.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import org.objectweb.asm.tree.ClassNode
3636
import org.objectweb.asm.tree.MethodNode
3737

3838
class WrapMethodHandler : InjectorAnnotationHandler() {
39+
override val allowCoerce get() = true
40+
3941
override fun expectedMethodSignature(
4042
annotation: PsiAnnotation,
4143
targetClass: ClassNode,

src/main/kotlin/platform/mixin/util/MixinConstants.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ object MixinConstants {
9393
const val LOCAL_REF_PACKAGE = "com.llamalad7.mixinextras.sugar.ref."
9494
const val EXPRESSION = "com.llamalad7.mixinextras.expression.Expression"
9595
const val DEFINITION = "com.llamalad7.mixinextras.expression.Definition"
96+
const val MIXIN_EXTRAS_CONFIG = "com.llamalad7.mixinextras.config.MixinExtrasConfig"
97+
const val MIXIN_EXTRAS_CONFIG_KEY = "mixinextras"
98+
const val MIXIN_EXTRAS_SERIALIZED_NAME = "com.llamalad7.mixinextras.lib.gson.annotations.SerializedName"
9699

97100
fun PsiType.unwrapLocalRef(): PsiType {
98101
if (this !is PsiClassType) {

0 commit comments

Comments
 (0)