diff options
author | Jonas Herzig <jonas@spark-squared.com> | 2021-11-13 09:49:17 +0100 |
---|---|---|
committer | Jonas Herzig <jonas@spark-squared.com> | 2021-11-13 10:28:09 +0100 |
commit | 26107cde7a9c47e444878736a9c34b64744c5f00 (patch) | |
tree | bc11fa2540daf0a82e713b2f749daededce38dba /src | |
parent | b00673f859058ff180dc16c22e12ac5698ffbab2 (diff) | |
download | Remap-26107cde7a9c47e444878736a9c34b64744c5f00.tar.gz Remap-26107cde7a9c47e444878736a9c34b64744c5f00.tar.bz2 Remap-26107cde7a9c47e444878736a9c34b64744c5f00.zip |
Support multi-target mixin injectors
Diffstat (limited to 'src')
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; |