CadixDev / Mercury

A source transformation and -remapping framework for Java.
Eclipse Public License 2.0
54 stars 23 forks source link

Handle more cases when anonymous classes are remapped #31

Closed DenWav closed 4 years ago

DenWav commented 4 years ago

In Java bytecode anonymous classes really aren't any different than any other class, except for a few minor details. These differences don't matter at all to the remapping process. SomeClass$1 could be remapped to SomeClass$200 or even SomeClass$AnotherClass and it would decompile the same, since in bytecode these are just class references. In source code however, anonymous class naming is very important and isn't nearly as flexible. They are generated by the compiler based on their location in the source file, which makes them very fragile to changes.

For bytecode remapping this isn't an issue, but we do need to worry about this for source code remapping. When this mapping comes along:

net/minecraft/SomeClass$1 -> net/minecraft/SomeClass$10

It's actually rather unclear what that even means from a source code perspective, and handling that remapping case is unclear. This commit attempts to address this by being a little more flexible when remapping members of anonymous classes by doing the following:

  1. First, check for the member signature in the class the member is in
  2. If the first check fails, check if the member is inside an anonymous class. If not, skip to step 5.
  3. Look for a sibling class of the original class whose obfuscated name matches our original class's deobfuscated name. If found, check for the member signature there.
  4. If that doesn't work, look for a sibling class of the original class whose deobfuscated name matches our original class's obfuscated name. If found, check for the member signature there.
  5. If none of those checks work, complete the original class's mappings with the inheritanceProvider and check one final time.

A few notes to point out:

DenWav commented 4 years ago

PR updated to handle fields and methods (generified it to just "members") and added unit test cases.