Unverified Commit d6142746 authored by Jamie Mansfield's avatar Jamie Mansfield
Browse files

Add map method for method local variables

parent 6f987c38
Pipeline #11078 passed with stage
in 8 minutes and 35 seconds
......@@ -5,4 +5,5 @@ Remi Forax <forax>
Remi Forax <forax@univ-mlv.fr>
Eugene Kuleshov <ekuleshov>
Andrei Loskutov <andrei>
Jamie Mansfield <jmansfield@cadixdev.org> <dev@jamierocks.uk>
......@@ -192,7 +192,7 @@ public class ClassRemapper extends ClassVisitor {
remappedDescriptor,
remapper.mapSignature(signature, false),
exceptions == null ? null : remapper.mapTypes(exceptions));
return methodVisitor == null ? null : createMethodRemapper(methodVisitor);
return methodVisitor == null ? null : createMethodRemapper(methodVisitor, name, descriptor);
}
@Override
......@@ -244,10 +244,13 @@ public class ClassRemapper extends ClassVisitor {
* {@link MethodRemapper}.
*
* @param methodVisitor the MethodVisitor the remapper must delegate to.
* @param name the name of the method
* @param descriptor the descriptor of the method
* @return the newly created remapper.
*/
protected MethodVisitor createMethodRemapper(final MethodVisitor methodVisitor) {
return new MethodRemapper(api, methodVisitor, remapper);
protected MethodVisitor createMethodRemapper(
final MethodVisitor methodVisitor, final String name, final String descriptor) {
return new MethodRemapper(api, methodVisitor, remapper, className, name, descriptor);
}
/**
......
......@@ -45,15 +45,39 @@ public class MethodRemapper extends MethodVisitor {
/** The remapper used to remap the types in the visited field. */
protected final Remapper remapper;
/** The name of the class that contains the method. */
private final String className;
/** The name of the method itself. */
private final String methodName;
/** The descriptor of the method itself. */
private final String methodDescriptor;
/**
* Constructs a new {@link MethodRemapper}. <i>Subclasses must not use this constructor</i>.
* Instead, they must use the {@link #MethodRemapper(int,MethodVisitor,Remapper)} version.
* Instead, they must use the {@link
* #MethodRemapper(int,MethodVisitor,Remapper,String,String,String)} version.
*
* @param methodVisitor the method visitor this remapper must delegate to.
* @param remapper the remapper to use to remap the types in the visited method.
* @param className the name of the class
* @param methodName the name of the method
* @param methodDescriptor the descriptor of the method
*/
public MethodRemapper(final MethodVisitor methodVisitor, final Remapper remapper) {
this(/* latest api = */ Opcodes.ASM9, methodVisitor, remapper);
public MethodRemapper(
final MethodVisitor methodVisitor,
final Remapper remapper,
final String className,
final String methodName,
final String methodDescriptor) {
this(
/* latest api = */ Opcodes.ASM9,
methodVisitor,
remapper,
className,
methodName,
methodDescriptor);
}
/**
......@@ -65,11 +89,22 @@ public class MethodRemapper extends MethodVisitor {
* org.objectweb.asm.Opcodes#ASM8} or {@link org.objectweb.asm.Opcodes#ASM9}.
* @param methodVisitor the method visitor this remapper must delegate to.
* @param remapper the remapper to use to remap the types in the visited method.
* @param className the name of the class
* @param methodName the name of the method
* @param methodDescriptor the descriptor of the method
*/
protected MethodRemapper(
final int api, final MethodVisitor methodVisitor, final Remapper remapper) {
final int api,
final MethodVisitor methodVisitor,
final Remapper remapper,
final String className,
final String methodName,
final String methodDescriptor) {
super(api, methodVisitor);
this.remapper = remapper;
this.className = className;
this.methodName = methodName;
this.methodDescriptor = methodDescriptor;
}
@Override
......@@ -238,7 +273,8 @@ public class MethodRemapper extends MethodVisitor {
final Label end,
final int index) {
super.visitLocalVariable(
name,
remapper.mapMethodLocalVariableName(
className, methodName, methodDescriptor, name, descriptor, index),
remapper.mapDesc(descriptor),
remapper.mapSignature(signature, true),
start,
......
......@@ -286,6 +286,27 @@ public abstract class Remapper {
return name;
}
/**
* Maps a local variable within a method to its new name. The default implementation of this
* method returns the given name, unchanged. Subclasses can override.
*
* @param owner the internal name of the owner class of the method.
* @param methodName the name of the method.
* @param name the name of the local variable.
* @param descriptor the descriptor of the local variable.
* @param index the index of the local variable.
* @return the new name of the local variable
*/
public String mapMethodLocalVariableName(
final String owner,
final String methodName,
final String methodDescriptor,
final String name,
final String descriptor,
final int index) {
return name;
}
/**
* Maps an invokedynamic or a constant dynamic method name to its new name. The default
* implementation of this method returns the given name, unchanged. Subclasses can override.
......
......@@ -44,6 +44,7 @@ import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.ConstantDynamic;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
......@@ -147,6 +148,40 @@ public class ClassRemapperTest extends AsmTest {
assertEquals("b", classNode.innerClasses.get(0).innerName);
}
@Test
public void testVisitMethod_visitLocalVariable() {
ClassNode classNode = new ClassNode();
ClassRemapper remapper =
new ClassRemapper(
classNode,
new Remapper() {
@Override
public String mapMethodLocalVariableName(
final String owner,
final String methodName,
final String methodDescriptor,
final String name,
final String descriptor,
final int index) {
if ("a".equals(name)) {
return "param1";
}
if ("b".equals(name)) {
return "param2";
}
return name;
}
});
remapper.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "pkg/C", null, "java/lang/Object", null);
MethodVisitor visitor = remapper.visitMethod(Opcodes.ACC_PUBLIC, "a", "(IZ)V", null, null);
visitor.visitLocalVariable("a", "I", null, new Label(), new Label(), 1);
visitor.visitLocalVariable("b", "Z", null, new Label(), new Label(), 2);
assertEquals("param1", classNode.methods.get(0).localVariables.get(0).name);
assertEquals("param2", classNode.methods.get(0).localVariables.get(1).name);
}
@Test
public void testVisitAttribute_moduleHashes() {
ClassNode classNode = new ClassNode();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment