From 2db91a420239dd95fcb086905a724be90b5a03fb Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Sun, 19 Aug 2018 13:00:29 +0100 Subject: [PATCH] Actually remap inner class names --- .../objectweb/asm/commons/ClassRemapper.java | 2 +- .../org/objectweb/asm/commons/Remapper.java | 20 +++++++++++++++++++ .../asm/commons/ClassRemapperTest.java | 20 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java index 18251dc2..7ecdc313 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java @@ -168,7 +168,7 @@ public class ClassRemapper extends ClassVisitor { super.visitInnerClass( remapper.mapType(name), outerName == null ? null : remapper.mapType(outerName), - innerName, + innerName == null ? null : remapper.mapInnerClassName(name, outerName, innerName), access); } diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java index d4f59690..0a0e7cab 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java @@ -214,6 +214,26 @@ public abstract class Remapper { return new SignatureRemapper(signatureVisitor, this); } + /** + * Maps an inner class name to its new name. The default implementation of this method provides a + * strategy that will work for inner classes produced by Java, but not necessarily other + * languages. Subclasses can override. + * + * @param name the fully-qualified internal name of the inner class. + * @param ownerName the internal name of the owner class of the inner class. + * @param innerName the internal name of the inner class. + * @return the new inner name of the inner class. + */ + public String mapInnerClassName( + final String name, final String ownerName, final String innerName) { + final String remappedInnerName = this.mapType(name); + if (remappedInnerName.contains("$")) { + return remappedInnerName.substring(remappedInnerName.lastIndexOf('$') + 1); + } else { + return innerName; + } + } + /** * Maps a method name to its new name. The default implementation of this method returns the given * name, unchanged. Subclasses can override. diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java index 6af394c4..30ef0d0a 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java @@ -58,6 +58,26 @@ public class ClassRemapperTest extends AsmTest { assertEquals("new/pkg/C", classNode.name); } + @Test + public void testRenameInnerClass() { + final ClassNode node = new ClassNode(); + final ClassRemapper remapper = + new ClassRemapper( + node, + new Remapper() { + @Override + public String map(final String internalName) { + if ("a".equals(internalName)) return "pkg/Demo"; + if ("a$g".equals(internalName)) return "pkg/Demo$Container"; + return internalName; + } + }); + remapper.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "a", null, "java/lang/Object", null); + remapper.visitInnerClass("a$g", "a", "g", Opcodes.ACC_PUBLIC); + assertEquals("pkg/Demo", node.innerClasses.get(0).outerName); + assertEquals("Container", node.innerClasses.get(0).innerName); + } + @Test public void testRenameModuleHashes() { ClassNode classNode = new ClassNode(); -- GitLab