From e4f4ef62f9d0b18946ad2222e07771da354a0b7a Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Tue, 2 Jan 2024 18:06:27 -0700 Subject: [PATCH] fix anonymous classes not being resolved --- .../com/replaymod/gradle/remap/PsiMapper.kt | 41 ++++++++++++++++++- .../remap/mapper/mixin/TestMixinShadow.kt | 20 +++++++++ src/test/resources/mappings.srg | 2 + src/testA/java/a/pkg/A.java | 7 ++++ src/testB/java/b/pkg/B.java | 7 ++++ 5 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/replaymod/gradle/remap/PsiMapper.kt b/src/main/kotlin/com/replaymod/gradle/remap/PsiMapper.kt index 5dba364..e7752bb 100644 --- a/src/main/kotlin/com/replaymod/gradle/remap/PsiMapper.kt +++ b/src/main/kotlin/com/replaymod/gradle/remap/PsiMapper.kt @@ -12,6 +12,8 @@ import org.jetbrains.kotlin.com.intellij.openapi.project.Project import org.jetbrains.kotlin.com.intellij.openapi.util.TextRange import org.jetbrains.kotlin.com.intellij.openapi.util.text.StringUtil import org.jetbrains.kotlin.com.intellij.psi.* +import org.jetbrains.kotlin.com.intellij.psi.impl.compiled.ClsClassImpl +import org.jetbrains.kotlin.com.intellij.psi.impl.java.stubs.JavaStubElementTypes import org.jetbrains.kotlin.com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.com.intellij.psi.util.ClassUtil import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor @@ -88,11 +90,46 @@ internal class PsiMapper( return Pair(result, errors) } - private fun findPsiClass(name: String, project: Project = file.project) = - JavaPsiFacade.getInstance(project).findClass( + private fun findPsiClass(name: String, project: Project = file.project): PsiClass? { + val value = JavaPsiFacade.getInstance(project).findClass( name.replace('/', '.').replace('$', '.'), GlobalSearchScope.allScope(project), ) + if (value == null) { + // failed to find? is anonymous class? + val dollarIndex = name.lastIndexOf('$') + if (dollarIndex != -1) { + val afterDollar = name.substring(dollarIndex + 1) + if (afterDollar.toIntOrNull() != null) { + val outerName = name.substring(0, dollarIndex) + val outer = findPsiClass(outerName, project) ?: return null + if (outer is ClsClassImpl) { + // for some reason anonymous are excluded -_- + return outer.stub.getChildrenByType(JavaStubElementTypes.CLASS, PsiClass.ARRAY_FACTORY).firstOrNull { + it.name == afterDollar + } + } else { + // visit outer class with a visitor and return on anonymous class that matches + var result: PsiClass? = null + outer.acceptChildren(object : JavaRecursiveElementVisitor() { + override fun visitAnonymousClass(aClass: PsiAnonymousClass) { + if (aClass.dollarQualifiedName.equals(name.replace('/', '.'))) { + result = aClass + } + super.visitClass(aClass) + } + + override fun visitElement(element: PsiElement) { + System.err.println("Visiting ${element.javaClass.simpleName} in ${outer.name}") + } + }) + return result + } + } + } + } + return value + } private fun map(expr: PsiElement, field: PsiField) { val fieldName = field.name ?: return diff --git a/src/test/kotlin/com/replaymod/gradle/remap/mapper/mixin/TestMixinShadow.kt b/src/test/kotlin/com/replaymod/gradle/remap/mapper/mixin/TestMixinShadow.kt index 4f76c97..0e01b69 100644 --- a/src/test/kotlin/com/replaymod/gradle/remap/mapper/mixin/TestMixinShadow.kt +++ b/src/test/kotlin/com/replaymod/gradle/remap/mapper/mixin/TestMixinShadow.kt @@ -23,4 +23,24 @@ class TestMixinShadow { } """.trimIndent() } + + + @Test + fun `resolve shadow names in anonymous classes`() { + TestData.remap(""" + @org.spongepowered.asm.mixin.Mixin(targets = "a.pkg.A$2") + abstract class MixinA { + @org.spongepowered.asm.mixin.Shadow + protected abstract void aMethodAnon(); + private void test() { this.aMethodAnon(); } + } + """.trimIndent()) shouldBe """ + @org.spongepowered.asm.mixin.Mixin(targets = "b.pkg.B$2") + abstract class MixinA { + @org.spongepowered.asm.mixin.Shadow + protected abstract void bMethodAnon(); + private void test() { this.bMethodAnon(); } + } + """.trimIndent() + } } \ No newline at end of file diff --git a/src/test/resources/mappings.srg b/src/test/resources/mappings.srg index 65cad17..2729bc8 100644 --- a/src/test/resources/mappings.srg +++ b/src/test/resources/mappings.srg @@ -24,6 +24,8 @@ MD: a/pkg/A/aOverloaded (Z)V b/pkg/B/bOverloaded (Z)V MD: a/pkg/A/commonOverloaded (Ljava/lang/Object;)V b/pkg/B/commonOverloaded (Ljava/lang/Object;)V MD: a/pkg/A/commonOverloaded (La/pkg/A;)V b/pkg/B/commonOverloaded (La/pkg/B;)V CL: a/pkg/A$1 b/pkg/B$1 +CL: a/pkg/A$2 b/pkg/B$2 +MD: a/pkg/A$2/aMethodAnon ()V b/pkg/B$2/bMethodAnon ()V CL: a/pkg/A$Inner b/pkg/B$Inner FD: a/pkg/A$Inner/aField b/pkg/B$Inner/bField CL: a/pkg/A$InnerA b/pkg/B$InnerB diff --git a/src/testA/java/a/pkg/A.java b/src/testA/java/a/pkg/A.java index be9bc1b..e8db972 100644 --- a/src/testA/java/a/pkg/A.java +++ b/src/testA/java/a/pkg/A.java @@ -101,6 +101,13 @@ public void aInterfaceMethod() { new A() {}; } + public void aAnon() { + new A() { + public void aMethodAnon() { + } + }; + } + public static void supplier(Supplier supplier) { } diff --git a/src/testB/java/b/pkg/B.java b/src/testB/java/b/pkg/B.java index 67d2ea8..676f446 100644 --- a/src/testB/java/b/pkg/B.java +++ b/src/testB/java/b/pkg/B.java @@ -98,6 +98,13 @@ public void bInterfaceMethod() { new B() {}; } + public void bAnon() { + new B() { + public void bMethodAnon() { + } + }; + } + public class Inner { private int bField; }