diff --git a/README.md b/README.md index d0fa325..604409a 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,10 @@ This makes it easy to see how our fork differs from the official release. ## Current Version -The current sources are based on the following version of ASM ([browse tags here](http://websvn.ow2.org/listing.php?repname=asm&path=%2Ftags%2F&peg=1748)): +The current sources are based on the following version of ASM ([browse tags here](http://websvn.ow2.org/listing.php?repname=asm&path=%2Ftags%2F)): ``` -Version 5.0.4, SVN r1779, tags/ASM_5_0_4 +Version 5.1, SVN r1798, tags/ASM_5_1 ``` Previous ASM Upgrade PR: https://github.com/scala/scala-asm/pull/5 diff --git a/src/main/java/scala/tools/asm/ClassReader.java b/src/main/java/scala/tools/asm/ClassReader.java index 47039b0..e3acb31 100644 --- a/src/main/java/scala/tools/asm/ClassReader.java +++ b/src/main/java/scala/tools/asm/ClassReader.java @@ -2496,11 +2496,12 @@ public Object readConst(final int item, final char[] buf) { int tag = readByte(index); int[] items = this.items; int cpIndex = items[readUnsignedShort(index + 1)]; + boolean itf = b[cpIndex - 1] == ClassWriter.IMETH; String owner = readClass(cpIndex, buf); cpIndex = items[readUnsignedShort(cpIndex + 2)]; String name = readUTF8(cpIndex, buf); String desc = readUTF8(cpIndex + 2, buf); - return new Handle(tag, owner, name, desc); + return new Handle(tag, owner, name, desc, itf); } } } diff --git a/src/main/java/scala/tools/asm/ClassWriter.java b/src/main/java/scala/tools/asm/ClassWriter.java index a8cebb9..a9e93c2 100644 --- a/src/main/java/scala/tools/asm/ClassWriter.java +++ b/src/main/java/scala/tools/asm/ClassWriter.java @@ -1052,7 +1052,7 @@ Item newConstItem(final Object cst) { } } else if (cst instanceof Handle) { Handle h = (Handle) cst; - return newHandleItem(h.tag, h.owner, h.name, h.desc); + return newHandleItem(h.tag, h.owner, h.name, h.desc, h.itf); } else { throw new IllegalArgumentException("value " + cst); } @@ -1187,10 +1187,12 @@ public int newMethodType(final String methodDesc) { * the name of the field or method. * @param desc * the descriptor of the field or method. + * @param itf + * true if the owner is an interface. * @return a new or an already existing method type reference item. */ Item newHandleItem(final int tag, final String owner, final String name, - final String desc) { + final String desc, final boolean itf) { key4.set(HANDLE_BASE + tag, owner, name, desc); Item result = get(key4); if (result == null) { @@ -1199,8 +1201,7 @@ Item newHandleItem(final int tag, final String owner, final String name, } else { put112(HANDLE, tag, - newMethod(owner, name, desc, - tag == Opcodes.H_INVOKEINTERFACE)); + newMethod(owner, name, desc, itf)); } result = new Item(index++, key4); put(result); @@ -1230,10 +1231,44 @@ Item newHandleItem(final int tag, final String owner, final String name, * the descriptor of the field or method. * @return the index of a new or already existing method type reference * item. + * + * @deprecated this method is superseded by + * {@link #newHandle(int, String, String, String, boolean)}. */ + @Deprecated public int newHandle(final int tag, final String owner, final String name, final String desc) { - return newHandleItem(tag, owner, name, desc).index; + return newHandle(tag, owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE); + } + + /** + * Adds a handle to the constant pool of the class being build. Does nothing + * if the constant pool already contains a similar item. This method is + * intended for {@link Attribute} sub classes, and is normally not needed by + * class generators or adapters. + * + * @param tag + * the kind of this handle. Must be {@link Opcodes#H_GETFIELD}, + * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, + * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, + * {@link Opcodes#H_INVOKESTATIC}, + * {@link Opcodes#H_INVOKESPECIAL}, + * {@link Opcodes#H_NEWINVOKESPECIAL} or + * {@link Opcodes#H_INVOKEINTERFACE}. + * @param owner + * the internal name of the field or method owner class. + * @param name + * the name of the field or method. + * @param desc + * the descriptor of the field or method. + * @param itf + * true if the owner is an interface. + * @return the index of a new or already existing method type reference + * item. + */ + public int newHandle(final int tag, final String owner, final String name, + final String desc, final boolean itf) { + return newHandleItem(tag, owner, name, desc, itf).index; } /** @@ -1265,7 +1300,7 @@ Item newInvokeDynamicItem(final String name, final String desc, int hashCode = bsm.hashCode(); bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name, - bsm.desc)); + bsm.desc, bsm.isInterface())); int argsLength = bsmArgs.length; bootstrapMethods.putShort(argsLength); diff --git a/src/main/java/scala/tools/asm/Context.java b/src/main/java/scala/tools/asm/Context.java index 2454696..782d431 100644 --- a/src/main/java/scala/tools/asm/Context.java +++ b/src/main/java/scala/tools/asm/Context.java @@ -142,4 +142,4 @@ class Context { * The stack values of the latest stack map frame that has been parsed. */ Object[] stack; -} +} \ No newline at end of file diff --git a/src/main/java/scala/tools/asm/Handle.java b/src/main/java/scala/tools/asm/Handle.java index cf12bb7..0a4863c 100644 --- a/src/main/java/scala/tools/asm/Handle.java +++ b/src/main/java/scala/tools/asm/Handle.java @@ -64,6 +64,12 @@ public final class Handle { */ final String desc; + + /** + * Indicate if the owner is an interface or not. + */ + final boolean itf; + /** * Constructs a new field or method handle. * @@ -84,12 +90,44 @@ public final class Handle { * @param desc * the descriptor of the field or method designated by this * handle. + * + * @deprecated this constructor has been superseded + * by {@link #Handle(int, String, String, String, boolean)}. */ + @Deprecated public Handle(int tag, String owner, String name, String desc) { + this(tag, owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE); + } + + /** + * Constructs a new field or method handle. + * + * @param tag + * the kind of field or method designated by this Handle. Must be + * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, + * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, + * {@link Opcodes#H_INVOKEVIRTUAL}, + * {@link Opcodes#H_INVOKESTATIC}, + * {@link Opcodes#H_INVOKESPECIAL}, + * {@link Opcodes#H_NEWINVOKESPECIAL} or + * {@link Opcodes#H_INVOKEINTERFACE}. + * @param owner + * the internal name of the class that owns the field or method + * designated by this handle. + * @param name + * the name of the field or method designated by this handle. + * @param desc + * the descriptor of the field or method designated by this + * handle. + * @param itf + * true if the owner is an interface. + */ + public Handle(int tag, String owner, String name, String desc, boolean itf) { this.tag = tag; this.owner = owner; this.name = name; this.desc = desc; + this.itf = itf; } /** @@ -135,6 +173,17 @@ public String getDesc() { return desc; } + /** + * Returns true if the owner of the field or method designated + * by this handle is an interface. + * + * @return true if the owner of the field or method designated + * by this handle is an interface. + */ + public boolean isInterface() { + return itf; + } + @Override public boolean equals(Object obj) { if (obj == this) { @@ -144,13 +193,13 @@ public boolean equals(Object obj) { return false; } Handle h = (Handle) obj; - return tag == h.tag && owner.equals(h.owner) && name.equals(h.name) - && desc.equals(h.desc); + return tag == h.tag && itf == h.itf && owner.equals(h.owner) + && name.equals(h.name) && desc.equals(h.desc); } @Override public int hashCode() { - return tag + owner.hashCode() * name.hashCode() * desc.hashCode(); + return tag + (itf? 64: 0) + owner.hashCode() * name.hashCode() * desc.hashCode(); } /** @@ -158,13 +207,16 @@ public int hashCode() { * representation is: * *
+     * for a reference to a class:
      * owner '.' name desc ' ' '(' tag ')'
+     * for a reference to an interface:
+     * owner '.' name desc ' ' '(' tag ' ' itf ')'
      * 
* * . As this format is unambiguous, it can be parsed if necessary. */ @Override public String toString() { - return owner + '.' + name + desc + " (" + tag + ')'; + return owner + '.' + name + desc + " (" + tag + (itf? " itf": "") + ')'; } } diff --git a/src/main/java/scala/tools/asm/MethodWriter.java b/src/main/java/scala/tools/asm/MethodWriter.java index ee54c4c..f05edb9 100644 --- a/src/main/java/scala/tools/asm/MethodWriter.java +++ b/src/main/java/scala/tools/asm/MethodWriter.java @@ -2040,7 +2040,7 @@ final int getSize() { } int size = 8; if (code.length > 0) { - if (code.length > 65536) { + if (code.length > 65535) { String nameString = ""; Item nameItem = cw.findItemByIndex(name); if (nameItem != null) nameString = nameItem.strVal1 +"'s "; diff --git a/src/main/java/scala/tools/asm/Type.java b/src/main/java/scala/tools/asm/Type.java index c8f0048..a0aa170 100644 --- a/src/main/java/scala/tools/asm/Type.java +++ b/src/main/java/scala/tools/asm/Type.java @@ -625,7 +625,7 @@ public int getArgumentsAndReturnSizes() { * @return the descriptor corresponding to this Java type. */ public String getDescriptor() { - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); getDescriptor(buf); return buf.toString(); } @@ -643,7 +643,7 @@ public String getDescriptor() { */ public static String getMethodDescriptor(final Type returnType, final Type... argumentTypes) { - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); buf.append('('); for (int i = 0; i < argumentTypes.length; ++i) { argumentTypes[i].getDescriptor(buf); @@ -660,7 +660,7 @@ public static String getMethodDescriptor(final Type returnType, * @param buf * the string buffer to which the descriptor must be appended. */ - private void getDescriptor(final StringBuffer buf) { + private void getDescriptor(final StringBuilder buf) { if (this.buf == null) { // descriptor is in byte 3 of 'off' for primitive types (buf == // null) @@ -700,7 +700,7 @@ public static String getInternalName(final Class c) { * @return the descriptor corresponding to the given class. */ public static String getDescriptor(final Class c) { - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); getDescriptor(buf, c); return buf.toString(); } @@ -714,7 +714,7 @@ public static String getDescriptor(final Class c) { */ public static String getConstructorDescriptor(final Constructor c) { Class[] parameters = c.getParameterTypes(); - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); buf.append('('); for (int i = 0; i < parameters.length; ++i) { getDescriptor(buf, parameters[i]); @@ -731,7 +731,7 @@ public static String getConstructorDescriptor(final Constructor c) { */ public static String getMethodDescriptor(final Method m) { Class[] parameters = m.getParameterTypes(); - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); buf.append('('); for (int i = 0; i < parameters.length; ++i) { getDescriptor(buf, parameters[i]); @@ -749,7 +749,7 @@ public static String getMethodDescriptor(final Method m) { * @param c * the class whose descriptor must be computed. */ - private static void getDescriptor(final StringBuffer buf, final Class c) { + private static void getDescriptor(final StringBuilder buf, final Class c) { Class d = c; while (true) { if (d.isPrimitive()) { diff --git a/src/main/java/scala/tools/asm/signature/SignatureWriter.java b/src/main/java/scala/tools/asm/signature/SignatureWriter.java index 65756ee..72c879d 100644 --- a/src/main/java/scala/tools/asm/signature/SignatureWriter.java +++ b/src/main/java/scala/tools/asm/signature/SignatureWriter.java @@ -40,9 +40,9 @@ public class SignatureWriter extends SignatureVisitor { /** - * Buffer used to construct the signature. + * Builder used to construct the signature. */ - private final StringBuffer buf = new StringBuffer(); + private final StringBuilder buf = new StringBuilder(); /** * Indicates if the signature contains formal type parameters. @@ -224,4 +224,4 @@ private void endArguments() { } argumentStack /= 2; } -} +} \ No newline at end of file diff --git a/src/main/java/scala/tools/asm/tree/IincInsnNode.java b/src/main/java/scala/tools/asm/tree/IincInsnNode.java index c37ac91..db50eab 100644 --- a/src/main/java/scala/tools/asm/tree/IincInsnNode.java +++ b/src/main/java/scala/tools/asm/tree/IincInsnNode.java @@ -80,4 +80,4 @@ public void accept(final MethodVisitor mv) { public AbstractInsnNode clone(final Map labels) { return new IincInsnNode(var, incr).cloneAnnotations(this); } -} +} \ No newline at end of file diff --git a/src/main/java/scala/tools/asm/tree/InsnList.java b/src/main/java/scala/tools/asm/tree/InsnList.java index acae4e9..9500feb 100644 --- a/src/main/java/scala/tools/asm/tree/InsnList.java +++ b/src/main/java/scala/tools/asm/tree/InsnList.java @@ -176,6 +176,9 @@ public ListIterator iterator() { /** * Returns an iterator over the instructions in this list. * + * @param index + * index of instruction for the iterator to start at + * * @return an iterator over the instructions in this list. */ @SuppressWarnings("unchecked") @@ -610,14 +613,28 @@ public int previousIndex() { } public void add(Object o) { - InsnList.this.insertBefore(next, (AbstractInsnNode) o); + if (next != null) { + InsnList.this.insertBefore(next, (AbstractInsnNode) o); + } else if (prev != null) { + InsnList.this.insert(prev, (AbstractInsnNode) o); + } else { + InsnList.this.add((AbstractInsnNode) o); + } prev = (AbstractInsnNode) o; remove = null; } public void set(Object o) { - InsnList.this.set(next.prev, (AbstractInsnNode) o); - prev = (AbstractInsnNode) o; + if (remove != null) { + InsnList.this.set(remove, (AbstractInsnNode) o); + if (remove == prev) { + prev = (AbstractInsnNode) o; + } else { + next = (AbstractInsnNode) o; + } + } else { + throw new IllegalStateException(); + } } } } diff --git a/src/main/java/scala/tools/asm/tree/InvokeDynamicInsnNode.java b/src/main/java/scala/tools/asm/tree/InvokeDynamicInsnNode.java index 0f85e60..d7fb3ee 100644 --- a/src/main/java/scala/tools/asm/tree/InvokeDynamicInsnNode.java +++ b/src/main/java/scala/tools/asm/tree/InvokeDynamicInsnNode.java @@ -99,4 +99,4 @@ public AbstractInsnNode clone(final Map labels) { return new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs) .cloneAnnotations(this); } -} +} \ No newline at end of file diff --git a/src/main/java/scala/tools/asm/tree/LabelNode.java b/src/main/java/scala/tools/asm/tree/LabelNode.java index 44c48c1..523a8d6 100644 --- a/src/main/java/scala/tools/asm/tree/LabelNode.java +++ b/src/main/java/scala/tools/asm/tree/LabelNode.java @@ -75,4 +75,4 @@ public AbstractInsnNode clone(final Map labels) { public void resetLabel() { label = null; } -} +} \ No newline at end of file diff --git a/src/main/java/scala/tools/asm/tree/LdcInsnNode.java b/src/main/java/scala/tools/asm/tree/LdcInsnNode.java index 1cc850b..c441081 100644 --- a/src/main/java/scala/tools/asm/tree/LdcInsnNode.java +++ b/src/main/java/scala/tools/asm/tree/LdcInsnNode.java @@ -76,4 +76,4 @@ public void accept(final MethodVisitor mv) { public AbstractInsnNode clone(final Map labels) { return new LdcInsnNode(cst).cloneAnnotations(this); } -} +} \ No newline at end of file diff --git a/src/main/java/scala/tools/asm/tree/MethodInsnNode.java b/src/main/java/scala/tools/asm/tree/MethodInsnNode.java index 5c8c835..651dec3 100644 --- a/src/main/java/scala/tools/asm/tree/MethodInsnNode.java +++ b/src/main/java/scala/tools/asm/tree/MethodInsnNode.java @@ -139,4 +139,4 @@ public void accept(final MethodVisitor mv) { public AbstractInsnNode clone(final Map labels) { return new MethodInsnNode(opcode, owner, name, desc, itf); } -} +} \ No newline at end of file diff --git a/src/main/java/scala/tools/asm/tree/MultiANewArrayInsnNode.java b/src/main/java/scala/tools/asm/tree/MultiANewArrayInsnNode.java index a8339a2..cff5345 100644 --- a/src/main/java/scala/tools/asm/tree/MultiANewArrayInsnNode.java +++ b/src/main/java/scala/tools/asm/tree/MultiANewArrayInsnNode.java @@ -81,4 +81,4 @@ public AbstractInsnNode clone(final Map labels) { return new MultiANewArrayInsnNode(desc, dims).cloneAnnotations(this); } -} +} \ No newline at end of file diff --git a/src/main/java/scala/tools/asm/tree/TableSwitchInsnNode.java b/src/main/java/scala/tools/asm/tree/TableSwitchInsnNode.java index fb17b9e..5d84f1a 100644 --- a/src/main/java/scala/tools/asm/tree/TableSwitchInsnNode.java +++ b/src/main/java/scala/tools/asm/tree/TableSwitchInsnNode.java @@ -111,4 +111,4 @@ public AbstractInsnNode clone(final Map labels) { return new TableSwitchInsnNode(min, max, clone(dflt, labels), clone( this.labels, labels)).cloneAnnotations(this); } -} +} \ No newline at end of file diff --git a/src/main/java/scala/tools/asm/tree/TypeInsnNode.java b/src/main/java/scala/tools/asm/tree/TypeInsnNode.java index 401400c..90172a8 100644 --- a/src/main/java/scala/tools/asm/tree/TypeInsnNode.java +++ b/src/main/java/scala/tools/asm/tree/TypeInsnNode.java @@ -88,4 +88,4 @@ public void accept(final MethodVisitor mv) { public AbstractInsnNode clone(final Map labels) { return new TypeInsnNode(opcode, desc).cloneAnnotations(this); } -} +} \ No newline at end of file diff --git a/src/main/java/scala/tools/asm/tree/VarInsnNode.java b/src/main/java/scala/tools/asm/tree/VarInsnNode.java index 685e4fc..1d52bf0 100644 --- a/src/main/java/scala/tools/asm/tree/VarInsnNode.java +++ b/src/main/java/scala/tools/asm/tree/VarInsnNode.java @@ -91,4 +91,4 @@ public void accept(final MethodVisitor mv) { public AbstractInsnNode clone(final Map labels) { return new VarInsnNode(opcode, var).cloneAnnotations(this); } -} +} \ No newline at end of file diff --git a/src/main/java/scala/tools/asm/tree/analysis/Subroutine.java b/src/main/java/scala/tools/asm/tree/analysis/Subroutine.java index d734bbd..5ce1bf0 100644 --- a/src/main/java/scala/tools/asm/tree/analysis/Subroutine.java +++ b/src/main/java/scala/tools/asm/tree/analysis/Subroutine.java @@ -87,4 +87,4 @@ public boolean merge(final Subroutine subroutine) throws AnalyzerException { } return changes; } -} +} \ No newline at end of file diff --git a/src/main/java/scala/tools/asm/util/ASMifier.java b/src/main/java/scala/tools/asm/util/ASMifier.java index 521e075..4b245eb 100644 --- a/src/main/java/scala/tools/asm/util/ASMifier.java +++ b/src/main/java/scala/tools/asm/util/ASMifier.java @@ -827,7 +827,11 @@ public Printer visitLocalVariableAnnotation(int typeRef, TypePath typePath, buf.append("{\n").append("av0 = ").append(name) .append(".visitLocalVariableAnnotation("); buf.append(typeRef); - buf.append(", TypePath.fromString(\"").append(typePath).append("\"), "); + if (typePath == null) { + buf.append(", null, "); + } else { + buf.append(", TypePath.fromString(\"").append(typePath).append("\"), "); + } buf.append("new Label[] {"); for (int i = 0; i < start.length; ++i) { buf.append(i == 0 ? " " : ", "); @@ -905,7 +909,11 @@ public ASMifier visitTypeAnnotation(final String method, final int typeRef, buf.append("{\n").append("av0 = ").append(name).append(".") .append(method).append("("); buf.append(typeRef); - buf.append(", TypePath.fromString(\"").append(typePath).append("\"), "); + if (typePath == null) { + buf.append(", null, "); + } else { + buf.append(", TypePath.fromString(\"").append(typePath).append("\"), "); + } appendConstant(desc); buf.append(", ").append(visible).append(");\n"); text.add(buf.toString()); diff --git a/src/main/java/scala/tools/asm/util/CheckMethodAdapter.java b/src/main/java/scala/tools/asm/util/CheckMethodAdapter.java index 48d5c3c..0577038 100644 --- a/src/main/java/scala/tools/asm/util/CheckMethodAdapter.java +++ b/src/main/java/scala/tools/asm/util/CheckMethodAdapter.java @@ -408,6 +408,9 @@ public CheckMethodAdapter(final MethodVisitor mv, * will not perform any data flow check (see * {@link #CheckMethodAdapter(int,String,String,MethodVisitor,Map)}). * + * @param api + * the ASM API version implemented by this CheckMethodAdapter. + * Must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. * @param mv * the method visitor to which this adapter must delegate calls. * @param labels diff --git a/src/main/java/scala/tools/asm/util/Printer.java b/src/main/java/scala/tools/asm/util/Printer.java index 773f129..c7e292d 100644 --- a/src/main/java/scala/tools/asm/util/Printer.java +++ b/src/main/java/scala/tools/asm/util/Printer.java @@ -142,6 +142,10 @@ public abstract class Printer { /** * Constructs a new {@link Printer}. + * + * @param api + * the ASM API version implemented by this printer. Must be one + * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. */ protected Printer(final int api) { this.api = api; @@ -150,34 +154,103 @@ protected Printer(final int api) { } /** - * Class header. See {@link scala.tools.asm.ClassVisitor#visit}. + * Class header. + * See {@link scala.tools.asm.ClassVisitor#visit}. + * + * @param version + * the class version. + * @param access + * the class's access flags (see {@link Opcodes}). This parameter + * also indicates if the class is deprecated. + * @param name + * the internal name of the class (see + * {@link scala.tools.asm.Type#getInternalName() getInternalName}). + * @param signature + * the signature of this class. May be null if the class + * is not a generic one, and does not extend or implement generic + * classes or interfaces. + * @param superName + * the internal of name of the super class (see + * {@link scala.tools.asm.Type#getInternalName() getInternalName}). + * For interfaces, the super class is {@link Object}. May be + * null, but only for the {@link Object} class. + * @param interfaces + * the internal names of the class's interfaces (see + * {@link scala.tools.asm.Type#getInternalName() getInternalName}). + * May be null. */ public abstract void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces); /** - * Class source. See {@link scala.tools.asm.ClassVisitor#visitSource}. + * Class source. + * See {@link scala.tools.asm.ClassVisitor#visitSource}. + * + * @param source + * the name of the source file from which the class was compiled. + * May be null. + * @param debug + * additional debug information to compute the correspondance + * between source and compiled elements of the class. May be + * null. */ - public abstract void visitSource(final String file, final String debug); + public abstract void visitSource(final String source, final String debug); /** - * Class outer class. See - * {@link scala.tools.asm.ClassVisitor#visitOuterClass}. + * Class outer class. + * See {@link scala.tools.asm.ClassVisitor#visitOuterClass}. + * + * Visits the enclosing class of the class. This method must be called only + * if the class has an enclosing class. + * + * @param owner + * internal name of the enclosing class of the class. + * @param name + * the name of the method that contains the class, or + * null if the class is not enclosed in a method of its + * enclosing class. + * @param desc + * the descriptor of the method that contains the class, or + * null if the class is not enclosed in a method of its + * enclosing class. */ public abstract void visitOuterClass(final String owner, final String name, final String desc); /** - * Class annotation. See - * {@link scala.tools.asm.ClassVisitor#visitAnnotation}. + * Class annotation. + * See {@link scala.tools.asm.ClassVisitor#visitAnnotation}. + * + * @param desc + * the class descriptor of the annotation class. + * @param visible + * true if the annotation is visible at runtime. + * @return the printer */ public abstract Printer visitClassAnnotation(final String desc, final boolean visible); /** - * Class type annotation. See - * {@link scala.tools.asm.ClassVisitor#visitTypeAnnotation}. + * Class type annotation. + * See {@link scala.tools.asm.ClassVisitor#visitTypeAnnotation}. + * + * @param typeRef + * a reference to the annotated type. The sort of this type + * reference must be + * {@link scala.tools.asm.TypeReference#CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER}, + * {@link scala.tools.asm.TypeReference#CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} + * or {@link scala.tools.asm.TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. + * See {@link scala.tools.asm.TypeReference}. + * @param typePath + * the path to the annotated type argument, wildcard bound, array + * element type, or static inner type within 'typeRef'. May be + * null if the annotation targets 'typeRef' as a whole. + * @param desc + * the class descriptor of the annotation class. + * @param visible + * true if the annotation is visible at runtime. + * @return the printer */ public Printer visitClassTypeAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) { @@ -185,26 +258,85 @@ public Printer visitClassTypeAnnotation(final int typeRef, } /** - * Class attribute. See - * {@link scala.tools.asm.ClassVisitor#visitAttribute}. + * Class attribute. + * See {@link scala.tools.asm.ClassVisitor#visitAttribute}. + * + * @param attr + * an attribute. */ public abstract void visitClassAttribute(final Attribute attr); /** - * Class inner name. See - * {@link scala.tools.asm.ClassVisitor#visitInnerClass}. + * Class inner name. + * See {@link scala.tools.asm.ClassVisitor#visitInnerClass}. + * + * @param name + * the internal name of an inner class (see + * {@link scala.tools.asm.Type#getInternalName() getInternalName}). + * @param outerName + * the internal name of the class to which the inner class + * belongs (see {@link scala.tools.asm.Type#getInternalName() getInternalName}). + * May be null for not member classes. + * @param innerName + * the (simple) name of the inner class inside its enclosing + * class. May be null for anonymous inner classes. + * @param access + * the access flags of the inner class as originally declared in + * the enclosing class. */ public abstract void visitInnerClass(final String name, final String outerName, final String innerName, final int access); /** - * Class field. See {@link scala.tools.asm.ClassVisitor#visitField}. + * Class field. + * See {@link scala.tools.asm.ClassVisitor#visitField}. + * + * @param access + * the field's access flags (see {@link Opcodes}). This parameter + * also indicates if the field is synthetic and/or deprecated. + * @param name + * the field's name. + * @param desc + * the field's descriptor (see {@link scala.tools.asm.Type Type}). + * @param signature + * the field's signature. May be null if the field's + * type does not use generic types. + * @param value + * the field's initial value. This parameter, which may be + * null if the field does not have an initial value, + * must be an {@link Integer}, a {@link Float}, a {@link Long}, a + * {@link Double} or a {@link String} (for int, + * float, long or String fields + * respectively). This parameter is only used for static + * fields. Its value is ignored for non static fields, which + * must be initialized through bytecode instructions in + * constructors or methods. + * @return the printer */ public abstract Printer visitField(final int access, final String name, final String desc, final String signature, final Object value); /** - * Class method. See {@link scala.tools.asm.ClassVisitor#visitMethod}. + * Class method. + * See {@link scala.tools.asm.ClassVisitor#visitMethod}. + * + * @param access + * the method's access flags (see {@link Opcodes}). This + * parameter also indicates if the method is synthetic and/or + * deprecated. + * @param name + * the method's name. + * @param desc + * the method's descriptor (see {@link scala.tools.asm.Type Type}). + * @param signature + * the method's signature. May be null if the method + * parameters, return type and exceptions do not use generic + * types. + * @param exceptions + * the internal names of the method's exception classes (see + * {@link scala.tools.asm.Type#getInternalName() getInternalName}). May be + * null. + * @return the printer */ public abstract Printer visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions); @@ -219,26 +351,64 @@ public abstract Printer visitMethod(final int access, final String name, // ------------------------------------------------------------------------ /** - * Annotation value. See {@link scala.tools.asm.AnnotationVisitor#visit}. + * Annotation value. + * See {@link scala.tools.asm.AnnotationVisitor#visit}. + * + * @param name + * the value name. + * @param value + * the actual value, whose type must be {@link Byte}, + * {@link Boolean}, {@link Character}, {@link Short}, + * {@link Integer} , {@link Long}, {@link Float}, {@link Double}, + * {@link String} or {@link scala.tools.asm.Type} + * or OBJECT or ARRAY sort. + * This value can also be an array of byte, boolean, short, char, int, + * long, float or double values (this is equivalent to using + * {@link #visitArray visitArray} and visiting each array element + * in turn, but is more convenient). */ public abstract void visit(final String name, final Object value); /** - * Annotation enum value. See - * {@link scala.tools.asm.AnnotationVisitor#visitEnum}. + * Annotation enum value. + * See {@link scala.tools.asm.AnnotationVisitor#visitEnum}. + * + * Visits an enumeration value of the annotation. + * + * @param name + * the value name. + * @param desc + * the class descriptor of the enumeration class. + * @param value + * the actual enumeration value. */ public abstract void visitEnum(final String name, final String desc, final String value); /** - * Nested annotation value. See - * {@link scala.tools.asm.AnnotationVisitor#visitAnnotation}. + * Nested annotation value. + * See {@link scala.tools.asm.AnnotationVisitor#visitAnnotation}. + * + * @param name + * the value name. + * @param desc + * the class descriptor of the nested annotation class. + * @return the printer */ public abstract Printer visitAnnotation(final String name, final String desc); /** - * Annotation array value. See - * {@link scala.tools.asm.AnnotationVisitor#visitArray}. + * Annotation array value. + * See {@link scala.tools.asm.AnnotationVisitor#visitArray}. + * + * Visits an array value of the annotation. Note that arrays of primitive + * types (such as byte, boolean, short, char, int, long, float or double) + * can be passed as value to {@link #visit visit}. This is what + * {@link scala.tools.asm.ClassReader} does. + * + * @param name + * the value name. + * @return the printer */ public abstract Printer visitArray(final String name); @@ -252,15 +422,35 @@ public abstract void visitEnum(final String name, final String desc, // ------------------------------------------------------------------------ /** - * Field annotation. See - * {@link scala.tools.asm.FieldVisitor#visitAnnotation}. + * Field annotation. + * See {@link scala.tools.asm.FieldVisitor#visitAnnotation}. + * + * @param desc + * the class descriptor of the annotation class. + * @param visible + * true if the annotation is visible at runtime. + * @return the printer */ public abstract Printer visitFieldAnnotation(final String desc, final boolean visible); /** - * Field type annotation. See - * {@link scala.tools.asm.FieldVisitor#visitTypeAnnotation}. + * Field type annotation. + * See {@link scala.tools.asm.FieldVisitor#visitTypeAnnotation}. + * + * @param typeRef + * a reference to the annotated type. The sort of this type + * reference must be {@link scala.tools.asm.TypeReference#FIELD FIELD}. + * See {@link scala.tools.asm.TypeReference}. + * @param typePath + * the path to the annotated type argument, wildcard bound, array + * element type, or static inner type within 'typeRef'. May be + * null if the annotation targets 'typeRef' as a whole. + * @param desc + * the class descriptor of the annotation class. + * @param visible + * true if the annotation is visible at runtime. + * @return the printer */ public Printer visitFieldTypeAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) { @@ -268,13 +458,17 @@ public Printer visitFieldTypeAnnotation(final int typeRef, } /** - * Field attribute. See - * {@link scala.tools.asm.FieldVisitor#visitAttribute}. + * Field attribute. + * See {@link scala.tools.asm.FieldVisitor#visitAttribute}. + * + * @param attr + * an attribute. */ public abstract void visitFieldAttribute(final Attribute attr); /** - * Field end. See {@link scala.tools.asm.FieldVisitor#visitEnd}. + * Field end. + * See {@link scala.tools.asm.FieldVisitor#visitEnd}. */ public abstract void visitFieldEnd(); @@ -283,29 +477,58 @@ public Printer visitFieldTypeAnnotation(final int typeRef, // ------------------------------------------------------------------------ /** - * Method parameter. See - * {@link scala.tools.asm.MethodVisitor#visitParameter(String, int)}. + * Method parameter. + * See {@link scala.tools.asm.MethodVisitor#visitParameter(String, int)}. + * + * @param name + * parameter name or null if none is provided. + * @param access + * the parameter's access flags, only ACC_FINAL, + * ACC_SYNTHETIC or/and ACC_MANDATED are + * allowed (see {@link Opcodes}). */ public void visitParameter(String name, int access) { throw new RuntimeException("Must be overridden"); } /** - * Method default annotation. See - * {@link scala.tools.asm.MethodVisitor#visitAnnotationDefault}. + * Method default annotation. + * See {@link scala.tools.asm.MethodVisitor#visitAnnotationDefault}. + * + * @return the printer */ public abstract Printer visitAnnotationDefault(); /** - * Method annotation. See - * {@link scala.tools.asm.MethodVisitor#visitAnnotation}. + * Method annotation. + * See {@link scala.tools.asm.MethodVisitor#visitAnnotation}. + * + * @param desc + * the class descriptor of the annotation class. + * @param visible + * true if the annotation is visible at runtime. + * @return the printer */ public abstract Printer visitMethodAnnotation(final String desc, final boolean visible); /** - * Method type annotation. See - * {@link scala.tools.asm.MethodVisitor#visitTypeAnnotation}. + * Method type annotation. + * See {@link scala.tools.asm.MethodVisitor#visitTypeAnnotation}. + * + * @param typeRef + * a reference to the annotated type. The sort of this type + * reference must be {@link scala.tools.asm.TypeReference#FIELD FIELD}. + * See {@link scala.tools.asm.TypeReference}. + * @param typePath + * the path to the annotated type argument, wildcard bound, array + * element type, or static inner type within 'typeRef'. May be + * null if the annotation targets 'typeRef' as a whole. + * @param desc + * the class descriptor of the annotation class. + * @param visible + * true if the annotation is visible at runtime. + * @return the printer */ public Printer visitMethodTypeAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) { @@ -313,64 +536,225 @@ public Printer visitMethodTypeAnnotation(final int typeRef, } /** - * Method parameter annotation. See - * {@link scala.tools.asm.MethodVisitor#visitParameterAnnotation}. + * Method parameter annotation. + * See {@link scala.tools.asm.MethodVisitor#visitParameterAnnotation}. + * + * @param parameter + * the parameter index. + * @param desc + * the class descriptor of the annotation class. + * @param visible + * true if the annotation is visible at runtime. + * @return the printer */ public abstract Printer visitParameterAnnotation(final int parameter, final String desc, final boolean visible); /** - * Method attribute. See - * {@link scala.tools.asm.MethodVisitor#visitAttribute}. + * Method attribute. + * See {@link scala.tools.asm.MethodVisitor#visitAttribute}. + * + * @param attr + * an attribute. */ public abstract void visitMethodAttribute(final Attribute attr); /** - * Method start. See {@link scala.tools.asm.MethodVisitor#visitCode}. + * Method start. + * See {@link scala.tools.asm.MethodVisitor#visitCode}. */ public abstract void visitCode(); /** - * Method stack frame. See - * {@link scala.tools.asm.MethodVisitor#visitFrame}. + * Method stack frame. + * See {@link scala.tools.asm.MethodVisitor#visitFrame}. + * + * Visits the current state of the local variables and operand stack + * elements. This method must(*) be called just before any + * instruction i that follows an unconditional branch instruction + * such as GOTO or THROW, that is the target of a jump instruction, or that + * starts an exception handler block. The visited types must describe the + * values of the local variables and of the operand stack elements just + * before i is executed.
+ *
+ * (*) this is mandatory only for classes whose version is greater than or + * equal to {@link Opcodes#V1_6 V1_6}.
+ *
+ * The frames of a method must be given either in expanded form, or in + * compressed form (all frames must use the same format, i.e. you must not + * mix expanded and compressed frames within a single method): + *
    + *
  • In expanded form, all frames must have the F_NEW type.
  • + *
  • In compressed form, frames are basically "deltas" from the state of + * the previous frame: + *
      + *
    • {@link Opcodes#F_SAME} representing frame with exactly the same + * locals as the previous frame and with the empty stack.
    • + *
    • {@link Opcodes#F_SAME1} representing frame with exactly the same + * locals as the previous frame and with single value on the stack ( + * nStack is 1 and stack[0] contains value for the + * type of the stack item).
    • + *
    • {@link Opcodes#F_APPEND} representing frame with current locals are + * the same as the locals in the previous frame, except that additional + * locals are defined (nLocal is 1, 2 or 3 and + * local elements contains values representing added types).
    • + *
    • {@link Opcodes#F_CHOP} representing frame with current locals are the + * same as the locals in the previous frame, except that the last 1-3 locals + * are absent and with the empty stack (nLocals is 1, 2 or 3).
    • + *
    • {@link Opcodes#F_FULL} representing complete frame data.
    • + *
    + *
  • + *
+ *
+ * In both cases the first frame, corresponding to the method's parameters + * and access flags, is implicit and must not be visited. Also, it is + * illegal to visit two or more frames for the same code location (i.e., at + * least one instruction must be visited between two calls to visitFrame). + * + * @param type + * the type of this stack map frame. Must be + * {@link Opcodes#F_NEW} for expanded frames, or + * {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, + * {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or + * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for + * compressed frames. + * @param nLocal + * the number of local variables in the visited frame. + * @param local + * the local variable types in this frame. This array must not be + * modified. Primitive types are represented by + * {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, + * {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, + * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or + * {@link Opcodes#UNINITIALIZED_THIS} (long and double are + * represented by a single element). Reference types are + * represented by String objects (representing internal names), + * and uninitialized types by Label objects (this label + * designates the NEW instruction that created this uninitialized + * value). + * @param nStack + * the number of operand stack elements in the visited frame. + * @param stack + * the operand stack types in this frame. This array must not be + * modified. Its content has the same format as the "local" + * array. + * @throws IllegalStateException + * if a frame is visited just after another one, without any + * instruction between the two (unless this frame is a + * Opcodes#F_SAME frame, in which case it is silently ignored). */ public abstract void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, final Object[] stack); /** - * Method instruction. See {@link scala.tools.asm.MethodVisitor#visitInsn} - * . + * Method instruction. + * See {@link scala.tools.asm.MethodVisitor#visitInsn} + * + * @param opcode + * the opcode of the instruction to be visited. This opcode is + * either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, + * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, + * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, + * LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, + * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, + * SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, + * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, + * IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, + * FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, + * IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, + * L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, + * LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN, + * DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, + * or MONITOREXIT. */ public abstract void visitInsn(final int opcode); /** - * Method instruction. See - * {@link scala.tools.asm.MethodVisitor#visitIntInsn}. + * Method instruction. + * See {@link scala.tools.asm.MethodVisitor#visitIntInsn}. + * + * @param opcode + * the opcode of the instruction to be visited. This opcode is + * either BIPUSH, SIPUSH or NEWARRAY. + * @param operand + * the operand of the instruction to be visited.
+ * When opcode is BIPUSH, operand value should be between + * Byte.MIN_VALUE and Byte.MAX_VALUE.
+ * When opcode is SIPUSH, operand value should be between + * Short.MIN_VALUE and Short.MAX_VALUE.
+ * When opcode is NEWARRAY, operand value should be one of + * {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR}, + * {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, + * {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT}, + * {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}. */ public abstract void visitIntInsn(final int opcode, final int operand); /** - * Method instruction. See - * {@link scala.tools.asm.MethodVisitor#visitVarInsn}. + * Method instruction. + * See {@link scala.tools.asm.MethodVisitor#visitVarInsn}. + * + * @param opcode + * the opcode of the local variable instruction to be visited. + * This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, + * ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET. + * @param var + * the operand of the instruction to be visited. This operand is + * the index of a local variable. */ public abstract void visitVarInsn(final int opcode, final int var); /** - * Method instruction. See - * {@link scala.tools.asm.MethodVisitor#visitTypeInsn}. + * Method instruction. + * See {@link scala.tools.asm.MethodVisitor#visitTypeInsn}. + * + /** + * Visits a type instruction. A type instruction is an instruction that + * takes the internal name of a class as parameter. + * + * @param opcode + * the opcode of the type instruction to be visited. This opcode + * is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF. + * @param type + * the operand of the instruction to be visited. This operand + * must be the internal name of an object or array class (see + * {@link scala.tools.asm.Type#getInternalName() getInternalName}). */ public abstract void visitTypeInsn(final int opcode, final String type); /** - * Method instruction. See - * {@link scala.tools.asm.MethodVisitor#visitFieldInsn}. + * Method instruction. + * See {@link scala.tools.asm.MethodVisitor#visitFieldInsn}. + * + * @param opcode + * the opcode of the type instruction to be visited. This opcode + * is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. + * @param owner + * the internal name of the field's owner class (see + * {@link scala.tools.asm.Type#getInternalName() getInternalName}). + * @param name + * the field's name. + * @param desc + * the field's descriptor (see {@link scala.tools.asm.Type Type}). */ public abstract void visitFieldInsn(final int opcode, final String owner, final String name, final String desc); /** - * Method instruction. See - * {@link scala.tools.asm.MethodVisitor#visitMethodInsn}. + * Method instruction. + * See {@link scala.tools.asm.MethodVisitor#visitMethodInsn}. + * + * @param opcode + * the opcode of the type instruction to be visited. This opcode + * is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or + * INVOKEINTERFACE. + * @param owner + * the internal name of the method's owner class (see + * {@link scala.tools.asm.Type#getInternalName() getInternalName}). + * @param name + * the method's name. + * @param desc + * the method's descriptor (see {@link scala.tools.asm.Type Type}). */ @Deprecated public void visitMethodInsn(final int opcode, final String owner, @@ -384,8 +768,22 @@ public void visitMethodInsn(final int opcode, final String owner, } /** - * Method instruction. See - * {@link scala.tools.asm.MethodVisitor#visitMethodInsn}. + * Method instruction. + * See {@link scala.tools.asm.MethodVisitor#visitMethodInsn}. + * + * @param opcode + * the opcode of the type instruction to be visited. This opcode + * is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or + * INVOKEINTERFACE. + * @param owner + * the internal name of the method's owner class (see + * {@link scala.tools.asm.Type#getInternalName() getInternalName}). + * @param name + * the method's name. + * @param desc + * the method's descriptor (see {@link scala.tools.asm.Type Type}). + * @param itf + * if the method's owner class is an interface. */ public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, final boolean itf) { @@ -401,59 +799,181 @@ public void visitMethodInsn(final int opcode, final String owner, } /** - * Method instruction. See - * {@link scala.tools.asm.MethodVisitor#visitInvokeDynamicInsn}. + * Method instruction. + * See {@link scala.tools.asm.MethodVisitor#visitInvokeDynamicInsn}. + * + * Visits an invokedynamic instruction. + * + * @param name + * the method's name. + * @param desc + * the method's descriptor (see {@link scala.tools.asm.Type Type}). + * @param bsm + * the bootstrap method. + * @param bsmArgs + * the bootstrap method constant arguments. Each argument must be + * an {@link Integer}, {@link Float}, {@link Long}, + * {@link Double}, {@link String}, {@link scala.tools.asm.Type} or {@link Handle} + * value. This method is allowed to modify the content of the + * array so a caller should expect that this array may change. */ public abstract void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs); /** - * Method instruction. See - * {@link scala.tools.asm.MethodVisitor#visitJumpInsn}. + * Method jump instruction. + * See {@link scala.tools.asm.MethodVisitor#visitJumpInsn}. + * + * @param opcode + * the opcode of the type instruction to be visited. This opcode + * is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, + * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, + * IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. + * @param label + * the operand of the instruction to be visited. This operand is + * a label that designates the instruction to which the jump + * instruction may jump. */ public abstract void visitJumpInsn(final int opcode, final Label label); /** - * Method label. See {@link scala.tools.asm.MethodVisitor#visitLabel}. + * Method label. + * See {@link scala.tools.asm.MethodVisitor#visitLabel}. + * + * @param label + * a {@link Label Label} object. */ public abstract void visitLabel(final Label label); /** - * Method instruction. See - * {@link scala.tools.asm.MethodVisitor#visitLdcInsn}. + * Method instruction. + * See {@link scala.tools.asm.MethodVisitor#visitLdcInsn}. + * + * Visits a LDC instruction. Note that new constant types may be added in + * future versions of the Java Virtual Machine. To easily detect new + * constant types, implementations of this method should check for + * unexpected constant types, like this: + * + *
+     * if (cst instanceof Integer) {
+     *     // ...
+     * } else if (cst instanceof Float) {
+     *     // ...
+     * } else if (cst instanceof Long) {
+     *     // ...
+     * } else if (cst instanceof Double) {
+     *     // ...
+     * } else if (cst instanceof String) {
+     *     // ...
+     * } else if (cst instanceof Type) {
+     *     int sort = ((Type) cst).getSort();
+     *     if (sort == Type.OBJECT) {
+     *         // ...
+     *     } else if (sort == Type.ARRAY) {
+     *         // ...
+     *     } else if (sort == Type.METHOD) {
+     *         // ...
+     *     } else {
+     *         // throw an exception
+     *     }
+     * } else if (cst instanceof Handle) {
+     *     // ...
+     * } else {
+     *     // throw an exception
+     * }
+     * 
+ * + * @param cst + * the constant to be loaded on the stack. This parameter must be + * a non null {@link Integer}, a {@link Float}, a {@link Long}, a + * {@link Double}, a {@link String}, a {@link scala.tools.asm.Type} + * of OBJECT or ARRAY sort for .class constants, for classes whose + * version is 49.0, a {@link scala.tools.asm.Type} of METHOD sort or a + * {@link Handle} for MethodType and MethodHandle constants, for + * classes whose version is 51.0. */ public abstract void visitLdcInsn(final Object cst); /** - * Method instruction. See - * {@link scala.tools.asm.MethodVisitor#visitIincInsn}. + * Method instruction. + * See {@link scala.tools.asm.MethodVisitor#visitIincInsn}. + * + * @param var + * index of the local variable to be incremented. + * @param increment + * amount to increment the local variable by. */ public abstract void visitIincInsn(final int var, final int increment); /** - * Method instruction. See - * {@link scala.tools.asm.MethodVisitor#visitTableSwitchInsn}. + * Method instruction. + * See {@link scala.tools.asm.MethodVisitor#visitTableSwitchInsn}. + * + * @param min + * the minimum key value. + * @param max + * the maximum key value. + * @param dflt + * beginning of the default handler block. + * @param labels + * beginnings of the handler blocks. labels[i] is the + * beginning of the handler block for the min + i key. */ public abstract void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels); /** - * Method instruction. See - * {@link scala.tools.asm.MethodVisitor#visitLookupSwitchInsn}. + * Method instruction. + * See {@link scala.tools.asm.MethodVisitor#visitLookupSwitchInsn}. + * + * @param dflt + * beginning of the default handler block. + * @param keys + * the values of the keys. + * @param labels + * beginnings of the handler blocks. labels[i] is the + * beginning of the handler block for the keys[i] key. */ public abstract void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels); /** - * Method instruction. See - * {@link scala.tools.asm.MethodVisitor#visitMultiANewArrayInsn}. + * Method instruction. + * See {@link scala.tools.asm.MethodVisitor#visitMultiANewArrayInsn}. + * + * @param desc + * an array type descriptor (see {@link scala.tools.asm.Type Type}). + * @param dims + * number of dimensions of the array to allocate. */ public abstract void visitMultiANewArrayInsn(final String desc, final int dims); /** - * Instruction type annotation. See - * {@link scala.tools.asm.MethodVisitor#visitInsnAnnotation}. + * Instruction type annotation. + * See {@link scala.tools.asm.MethodVisitor#visitInsnAnnotation}. + * + * @param typeRef + * a reference to the annotated type. The sort of this type + * reference must be {@link scala.tools.asm.TypeReference#INSTANCEOF INSTANCEOF}, + * {@link scala.tools.asm.TypeReference#NEW NEW}, + * {@link scala.tools.asm.TypeReference#CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, + * {@link scala.tools.asm.TypeReference#METHOD_REFERENCE METHOD_REFERENCE}, + * {@link scala.tools.asm.TypeReference#CAST CAST}, + * {@link scala.tools.asm.TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, + * {@link scala.tools.asm.TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT METHOD_INVOCATION_TYPE_ARGUMENT}, + * {@link scala.tools.asm.TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, + * or {@link scala.tools.asm.TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT METHOD_REFERENCE_TYPE_ARGUMENT}. + * See {@link scala.tools.asm.TypeReference}. + * @param typePath + * the path to the annotated type argument, wildcard bound, array + * element type, or static inner type within 'typeRef'. May be + * null if the annotation targets 'typeRef' as a whole. + * @param desc + * the class descriptor of the annotation class. + * @param visible + * true if the annotation is visible at runtime. + * @return the printer */ public Printer visitInsnAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) { @@ -461,15 +981,44 @@ public Printer visitInsnAnnotation(final int typeRef, } /** - * Method exception handler. See - * {@link scala.tools.asm.MethodVisitor#visitTryCatchBlock}. + * Method exception handler. + * See {@link scala.tools.asm.MethodVisitor#visitTryCatchBlock}. + * + * @param start + * beginning of the exception handler's scope (inclusive). + * @param end + * end of the exception handler's scope (exclusive). + * @param handler + * beginning of the exception handler's code. + * @param type + * internal name of the type of exceptions handled by the + * handler, or null to catch any exceptions (for + * "finally" blocks). + * @throws IllegalArgumentException + * if one of the labels has already been visited by this visitor + * (by the {@link #visitLabel visitLabel} method). */ public abstract void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type); /** - * Try catch block type annotation. See - * {@link scala.tools.asm.MethodVisitor#visitTryCatchAnnotation}. + * Try catch block type annotation. + * See {@link scala.tools.asm.MethodVisitor#visitTryCatchAnnotation}. + * + * @param typeRef + * a reference to the annotated type. The sort of this type + * reference must be {@link scala.tools.asm.TypeReference#EXCEPTION_PARAMETER + * EXCEPTION_PARAMETER}. + * See {@link scala.tools.asm.TypeReference}. + * @param typePath + * the path to the annotated type argument, wildcard bound, array + * element type, or static inner type within 'typeRef'. May be + * null if the annotation targets 'typeRef' as a whole. + * @param desc + * the class descriptor of the annotation class. + * @param visible + * true if the annotation is visible at runtime. + * @return the printer */ public Printer visitTryCatchAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) { @@ -477,16 +1026,62 @@ public Printer visitTryCatchAnnotation(final int typeRef, } /** - * Method debug info. See - * {@link scala.tools.asm.MethodVisitor#visitLocalVariable}. + * Method debug info. + * See {@link scala.tools.asm.MethodVisitor#visitLocalVariable}. + * + * @param name + * the name of a local variable. + * @param desc + * the type descriptor of this local variable. + * @param signature + * the type signature of this local variable. May be + * null if the local variable type does not use generic + * types. + * @param start + * the first instruction corresponding to the scope of this local + * variable (inclusive). + * @param end + * the last instruction corresponding to the scope of this local + * variable (exclusive). + * @param index + * the local variable's index. + * @throws IllegalArgumentException + * if one of the labels has not already been visited by this + * visitor (by the {@link #visitLabel visitLabel} method). */ public abstract void visitLocalVariable(final String name, final String desc, final String signature, final Label start, final Label end, final int index); /** - * Local variable type annotation. See - * {@link scala.tools.asm.MethodVisitor#visitTryCatchAnnotation}. + * Local variable type annotation. + * See {@link scala.tools.asm.MethodVisitor#visitTryCatchAnnotation}. + * + * @param typeRef + * a reference to the annotated type. The sort of this type + * reference must be {@link scala.tools.asm.TypeReference#LOCAL_VARIABLE + * LOCAL_VARIABLE} or {@link scala.tools.asm.TypeReference#RESOURCE_VARIABLE + * RESOURCE_VARIABLE}. + * See {@link scala.tools.asm.TypeReference}. + * @param typePath + * the path to the annotated type argument, wildcard bound, array + * element type, or static inner type within 'typeRef'. May be + * null if the annotation targets 'typeRef' as a whole. + * @param start + * the fist instructions corresponding to the continuous ranges + * that make the scope of this local variable (inclusive). + * @param end + * the last instructions corresponding to the continuous ranges + * that make the scope of this local variable (exclusive). This + * array must have the same size as the 'start' array. + * @param index + * the local variable's index in each range. This array must have + * the same size as the 'start' array. + * @param desc + * the class descriptor of the annotation class. + * @param visible + * true if the annotation is visible at runtime. + * @return the printer */ public Printer visitLocalVariableAnnotation(final int typeRef, final TypePath typePath, final Label[] start, final Label[] end, @@ -495,19 +1090,34 @@ public Printer visitLocalVariableAnnotation(final int typeRef, } /** - * Method debug info. See - * {@link scala.tools.asm.MethodVisitor#visitLineNumber}. + * Method debug info. + * See {@link scala.tools.asm.MethodVisitor#visitLineNumber}. + * + * @param line + * a line number. This number refers to the source file from + * which the class was compiled. + * @param start + * the first instruction corresponding to this line number. + * @throws IllegalArgumentException + * if start has not already been visited by this + * visitor (by the {@link #visitLabel visitLabel} method). */ public abstract void visitLineNumber(final int line, final Label start); /** - * Method max stack and max locals. See - * {@link scala.tools.asm.MethodVisitor#visitMaxs}. + * Method max stack and max locals. + * See {@link scala.tools.asm.MethodVisitor#visitMaxs}. + * + * @param maxStack + * maximum stack size of the method. + * @param maxLocals + * maximum number of local variables for the method. */ public abstract void visitMaxs(final int maxStack, final int maxLocals); /** - * Method end. See {@link scala.tools.asm.MethodVisitor#visitEnd}. + * Method end. + * See {@link scala.tools.asm.MethodVisitor#visitEnd}. */ public abstract void visitMethodEnd(); @@ -586,4 +1196,4 @@ static void printList(final PrintWriter pw, final List l) { } } } -} +} \ No newline at end of file diff --git a/src/main/java/scala/tools/asm/util/TraceSignatureVisitor.java b/src/main/java/scala/tools/asm/util/TraceSignatureVisitor.java index f99ec2b..6e3af30 100644 --- a/src/main/java/scala/tools/asm/util/TraceSignatureVisitor.java +++ b/src/main/java/scala/tools/asm/util/TraceSignatureVisitor.java @@ -41,7 +41,7 @@ */ public final class TraceSignatureVisitor extends SignatureVisitor { - private final StringBuffer declaration; + private final StringBuilder declaration; private boolean isInterface; @@ -53,9 +53,9 @@ public final class TraceSignatureVisitor extends SignatureVisitor { private boolean seenInterface; - private StringBuffer returnType; + private StringBuilder returnType; - private StringBuffer exceptions; + private StringBuilder exceptions; /** * Stack used to keep track of class types that have arguments. Each element @@ -77,10 +77,10 @@ public final class TraceSignatureVisitor extends SignatureVisitor { public TraceSignatureVisitor(final int access) { super(Opcodes.ASM5); isInterface = (access & Opcodes.ACC_INTERFACE) != 0; - this.declaration = new StringBuffer(); + this.declaration = new StringBuilder(); } - private TraceSignatureVisitor(final StringBuffer buf) { + private TraceSignatureVisitor(final StringBuilder buf) { super(Opcodes.ASM5); this.declaration = buf; } @@ -146,14 +146,14 @@ public SignatureVisitor visitReturnType() { declaration.append('('); } declaration.append(')'); - returnType = new StringBuffer(); + returnType = new StringBuilder(); return new TraceSignatureVisitor(returnType); } @Override public SignatureVisitor visitExceptionType() { if (exceptions == null) { - exceptions = new StringBuffer(); + exceptions = new StringBuilder(); } else { exceptions.append(", "); }