Skip to content

Commit

Permalink
fix anonymous classes not being resolved
Browse files Browse the repository at this point in the history
  • Loading branch information
wagyourtail committed Jan 3, 2024
1 parent 7ccb777 commit 15e2568
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 2 deletions.
41 changes: 39 additions & 2 deletions src/main/kotlin/com/replaymod/gradle/remap/PsiMapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -96,11 +98,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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}
2 changes: 2 additions & 0 deletions src/test/resources/mappings.srg
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions src/testA/java/a/pkg/A.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ public void aInterfaceMethod() {
new A() {};
}

public void aAnon() {
new A() {
public void aMethodAnon() {
}
};
}

public static void supplier(Supplier<String> supplier) {
}

Expand Down
7 changes: 7 additions & 0 deletions src/testB/java/b/pkg/B.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ public void bInterfaceMethod() {
new B() {};
}

public void bAnon() {
new B() {
public void bMethodAnon() {
}
};
}

public class Inner {
private int bField;
}
Expand Down

0 comments on commit 15e2568

Please sign in to comment.