diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/StaticInitMerger.java b/asm-commons/src/main/java/org/objectweb/asm/commons/StaticInitMerger.java
index 70993ffc706f5c65a09a8c3310a1c3ad4308072c..b469a93e0ea903737aac2b809cfa10d8a1b5724b 100644
--- a/asm-commons/src/main/java/org/objectweb/asm/commons/StaticInitMerger.java
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/StaticInitMerger.java
@@ -32,27 +32,50 @@ import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
- * A {@link ClassVisitor} that merges clinit methods into a single one.
+ * A {@link ClassVisitor} that merges <clinit> methods into a single one. All the existing
+ * <clinit> methods are renamed, and a new one is created, which calls all the renamed
+ * methods.
*
* @author Eric Bruneton
*/
public class StaticInitMerger extends ClassVisitor {
- private String name;
+ /** The internal name of the visited class. */
+ private String owner;
- private MethodVisitor clinit;
+ /** The prefix to use to rename the existing <clinit> methods. */
+ private final String renamedClinitMethodPrefix;
- private final String prefix;
+ /** The number of <clinit> methods visited so far. */
+ private int numClinitMethods;
- private int counter;
+ /** The MethodVisitor for the merged <clinit> method. */
+ private MethodVisitor mergedClinitVisitor;
- public StaticInitMerger(final String prefix, final ClassVisitor cv) {
- this(Opcodes.ASM6, prefix, cv);
+ /**
+ * Constructs a new {@link StaticInitMerger}. Subclasses must not use this constructor.
+ * Instead, they must use the {@link #StaticInitMerger(int, String, ClassVisitor)} version.
+ *
+ * @param prefix the prefix to use to rename the existing <clinit> methods.
+ * @param classVisitor the class visitor to which this visitor must delegate method calls. May be
+ * null.
+ */
+ public StaticInitMerger(final String prefix, final ClassVisitor classVisitor) {
+ this(Opcodes.ASM6, prefix, classVisitor);
}
- protected StaticInitMerger(final int api, final String prefix, final ClassVisitor cv) {
- super(api, cv);
- this.prefix = prefix;
+ /**
+ * Constructs a new {@link StaticInitMerger}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of {@link
+ * Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
+ * @param prefix the prefix to use to rename the existing <clinit> methods.
+ * @param classVisitor the class visitor to which this visitor must delegate method calls. May be
+ * null.
+ */
+ protected StaticInitMerger(final int api, final String prefix, final ClassVisitor classVisitor) {
+ super(api, classVisitor);
+ this.renamedClinitMethodPrefix = prefix;
}
@Override
@@ -63,39 +86,39 @@ public class StaticInitMerger extends ClassVisitor {
final String signature,
final String superName,
final String[] interfaces) {
- cv.visit(version, access, name, signature, superName, interfaces);
- this.name = name;
+ super.visit(version, access, name, signature, superName, interfaces);
+ this.owner = name;
}
@Override
public MethodVisitor visitMethod(
final int access,
final String name,
- final String desc,
+ final String descriptor,
final String signature,
final String[] exceptions) {
- MethodVisitor mv;
+ MethodVisitor methodVisitor;
if ("".equals(name)) {
- int a = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC;
- String n = prefix + counter++;
- mv = cv.visitMethod(a, n, desc, signature, exceptions);
+ int newAccess = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC;
+ String newName = renamedClinitMethodPrefix + numClinitMethods++;
+ methodVisitor = super.visitMethod(newAccess, newName, descriptor, signature, exceptions);
- if (clinit == null) {
- clinit = cv.visitMethod(a, name, desc, null, null);
+ if (mergedClinitVisitor == null) {
+ mergedClinitVisitor = super.visitMethod(newAccess, name, descriptor, null, null);
}
- clinit.visitMethodInsn(Opcodes.INVOKESTATIC, this.name, n, desc, false);
+ mergedClinitVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, owner, newName, descriptor, false);
} else {
- mv = cv.visitMethod(access, name, desc, signature, exceptions);
+ methodVisitor = super.visitMethod(access, name, descriptor, signature, exceptions);
}
- return mv;
+ return methodVisitor;
}
@Override
public void visitEnd() {
- if (clinit != null) {
- clinit.visitInsn(Opcodes.RETURN);
- clinit.visitMaxs(0, 0);
+ if (mergedClinitVisitor != null) {
+ mergedClinitVisitor.visitInsn(Opcodes.RETURN);
+ mergedClinitVisitor.visitMaxs(0, 0);
}
- cv.visitEnd();
+ super.visitEnd();
}
}