aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Herzig <jonas@spark-squared.com>2021-11-13 09:49:17 +0100
committerJonas Herzig <jonas@spark-squared.com>2021-11-13 10:28:09 +0100
commit26107cde7a9c47e444878736a9c34b64744c5f00 (patch)
treebc11fa2540daf0a82e713b2f749daededce38dba
parentb00673f859058ff180dc16c22e12ac5698ffbab2 (diff)
downloadRemap-26107cde7a9c47e444878736a9c34b64744c5f00.tar.gz
Remap-26107cde7a9c47e444878736a9c34b64744c5f00.tar.bz2
Remap-26107cde7a9c47e444878736a9c34b64744c5f00.zip
Support multi-target mixin injectors
-rw-r--r--src/main/kotlin/com/replaymod/gradle/remap/PsiMapper.kt8
-rw-r--r--src/main/kotlin/com/replaymod/gradle/remap/PsiUtils.kt13
-rw-r--r--src/test/kotlin/com/replaymod/gradle/remap/mapper/mixin/TestMixinInjections.kt17
3 files changed, 31 insertions, 7 deletions
diff --git a/src/main/kotlin/com/replaymod/gradle/remap/PsiMapper.kt b/src/main/kotlin/com/replaymod/gradle/remap/PsiMapper.kt
index 412b6bf..a71c4d1 100644
--- a/src/main/kotlin/com/replaymod/gradle/remap/PsiMapper.kt
+++ b/src/main/kotlin/com/replaymod/gradle/remap/PsiMapper.kt
@@ -481,10 +481,8 @@ internal class PsiMapper(
?: method.getAnnotation(CLASS_REDIRECT)
?: return
- for (attribute in annotation.parameterList.attributes) {
- if ("method" != attribute.name) continue
- // Note: mixin supports multiple targets, we do not (yet)
- val (literalExpr, literalValue) = attribute.resolvedLiteralValue ?: continue
+ val methodAttrib = annotation.findDeclaredAttributeValue("method")
+ for ((literalExpr, literalValue) in methodAttrib?.resolvedLiteralValues ?: emptyList()) {
val (targetName, targetDesc) = if ('(' in literalValue) {
MethodSignature.of(literalValue).let { it.name to it.descriptor.toString() }
} else {
@@ -497,7 +495,7 @@ internal class PsiMapper(
}
} else {
if (targetMethods.size > 1) {
- error(attribute, "Ambiguous mixin method \"$targetName\" may refer to any of: ${targetMethods.joinToString {
+ error(literalExpr, "Ambiguous mixin method \"$targetName\" may refer to any of: ${targetMethods.joinToString {
"\"${it.name}${ClassUtil.getAsmMethodSignature(it)}\""
}}")
}
diff --git a/src/main/kotlin/com/replaymod/gradle/remap/PsiUtils.kt b/src/main/kotlin/com/replaymod/gradle/remap/PsiUtils.kt
index 936ab89..de42dcf 100644
--- a/src/main/kotlin/com/replaymod/gradle/remap/PsiUtils.kt
+++ b/src/main/kotlin/com/replaymod/gradle/remap/PsiUtils.kt
@@ -19,8 +19,11 @@ internal val PsiClass.dollarQualifiedName: String? get() {
return "$parentName$$selfName"
}
-internal val PsiNameValuePair.resolvedLiteralValue: Pair<PsiLiteralExpression, String>? get () {
- var value: PsiElement? = value
+internal val PsiNameValuePair.resolvedLiteralValue: Pair<PsiLiteralExpression, String>?
+ get () = value?.resolvedLiteralValue
+
+private val PsiElement.resolvedLiteralValue: Pair<PsiLiteralExpression, String>? get () {
+ var value: PsiElement? = this
while (value is PsiReferenceExpression) {
val resolved = value.resolve()
value = when (resolved) {
@@ -32,6 +35,12 @@ internal val PsiNameValuePair.resolvedLiteralValue: Pair<PsiLiteralExpression, S
return Pair(literal, StringUtil.unquoteString(literal.text))
}
+internal val PsiAnnotationMemberValue.resolvedLiteralValues: List<Pair<PsiLiteralExpression, String>>
+ get () = when (this) {
+ is PsiArrayInitializerMemberValue -> initializers.mapNotNull { it.resolvedLiteralValue }
+ else -> listOfNotNull(resolvedLiteralValue)
+ }
+
internal object PsiUtils {
fun getSignature(method: PsiMethod): MethodSignature = MethodSignature(method.name, getDescriptor(method))
diff --git a/src/test/kotlin/com/replaymod/gradle/remap/mapper/mixin/TestMixinInjections.kt b/src/test/kotlin/com/replaymod/gradle/remap/mapper/mixin/TestMixinInjections.kt
index 0cba1ae..da68496 100644
--- a/src/test/kotlin/com/replaymod/gradle/remap/mapper/mixin/TestMixinInjections.kt
+++ b/src/test/kotlin/com/replaymod/gradle/remap/mapper/mixin/TestMixinInjections.kt
@@ -162,6 +162,23 @@ class TestMixinInjections {
}
@Test
+ fun `remaps multiple methods`() {
+ TestData.remap("""
+ @org.spongepowered.asm.mixin.Mixin(a.pkg.A.class)
+ class MixinA {
+ @org.spongepowered.asm.mixin.injection.Inject(method = { "aMethod", "aInterfaceMethod" })
+ private void test() {}
+ }
+ """.trimIndent()) shouldBe """
+ @org.spongepowered.asm.mixin.Mixin(b.pkg.B.class)
+ class MixinA {
+ @org.spongepowered.asm.mixin.injection.Inject(method = { "bMethod", "bInterfaceMethod" })
+ private void test() {}
+ }
+ """.trimIndent()
+ }
+
+ @Test
fun `remaps @At target`() {
TestData.remap("""
import org.spongepowered.asm.mixin.injection.At;