diff --git a/parabotv2/src/org/objectweb/asm/AnnotationVisitor.java b/parabotv2/src/org/objectweb/asm/AnnotationVisitor.java
index 30d62c3..b644083 100644
--- a/parabotv2/src/org/objectweb/asm/AnnotationVisitor.java
+++ b/parabotv2/src/org/objectweb/asm/AnnotationVisitor.java
@@ -41,7 +41,7 @@ public abstract class AnnotationVisitor {
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4}.
+ * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
*/
protected final int api;
@@ -52,28 +52,28 @@ public abstract class AnnotationVisitor {
protected AnnotationVisitor av;
/**
- * Constructs a new {@link org.objectweb.asm.AnnotationVisitor}.
+ * Constructs a new {@link AnnotationVisitor}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
*/
public AnnotationVisitor(final int api) {
this(api, null);
}
/**
- * Constructs a new {@link org.objectweb.asm.AnnotationVisitor}.
+ * Constructs a new {@link AnnotationVisitor}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
* @param av
* the annotation visitor to which this visitor must delegate
* method calls. May be null.
*/
public AnnotationVisitor(final int api, final AnnotationVisitor av) {
- if (api != Opcodes.ASM4) {
+ if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
throw new IllegalArgumentException();
}
this.api = api;
diff --git a/parabotv2/src/org/objectweb/asm/AnnotationWriter.java b/parabotv2/src/org/objectweb/asm/AnnotationWriter.java
index 3c7ef47..6b95608 100644
--- a/parabotv2/src/org/objectweb/asm/AnnotationWriter.java
+++ b/parabotv2/src/org/objectweb/asm/AnnotationWriter.java
@@ -30,7 +30,7 @@
package org.objectweb.asm;
/**
- * An {@link org.objectweb.asm.AnnotationVisitor} that generates annotations in bytecode form.
+ * An {@link AnnotationVisitor} that generates annotations in bytecode form.
*
* @author Eric Bruneton
* @author Eugene Kuleshov
@@ -88,7 +88,7 @@ final class AnnotationWriter extends AnnotationVisitor {
// ------------------------------------------------------------------------
/**
- * Constructs a new {@link org.objectweb.asm.AnnotationWriter}.
+ * Constructs a new {@link AnnotationWriter}.
*
* @param cw
* the class writer to which this annotation must be added.
@@ -104,7 +104,7 @@ final class AnnotationWriter extends AnnotationVisitor {
*/
AnnotationWriter(final ClassWriter cw, final boolean named,
final ByteVector bv, final ByteVector parent, final int offset) {
- super(Opcodes.ASM4);
+ super(Opcodes.ASM5);
this.cw = cw;
this.named = named;
this.bv = bv;
@@ -315,4 +315,57 @@ final class AnnotationWriter extends AnnotationVisitor {
}
}
}
+
+ /**
+ * Puts the given type reference and type path into the given bytevector.
+ * LOCAL_VARIABLE and RESOURCE_VARIABLE target types are not supported.
+ *
+ * @param typeRef
+ * a reference to the annotated type. See {@link 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 out
+ * where the type reference and type path must be put.
+ */
+ static void putTarget(int typeRef, TypePath typePath, ByteVector out) {
+ switch (typeRef >>> 24) {
+ case 0x00: // CLASS_TYPE_PARAMETER
+ case 0x01: // METHOD_TYPE_PARAMETER
+ case 0x16: // METHOD_FORMAL_PARAMETER
+ out.putShort(typeRef >>> 16);
+ break;
+ case 0x13: // FIELD
+ case 0x14: // METHOD_RETURN
+ case 0x15: // METHOD_RECEIVER
+ out.putByte(typeRef >>> 24);
+ break;
+ case 0x47: // CAST
+ case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+ case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
+ case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+ case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
+ out.putInt(typeRef);
+ break;
+ // case 0x10: // CLASS_EXTENDS
+ // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
+ // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
+ // case 0x17: // THROWS
+ // case 0x42: // EXCEPTION_PARAMETER
+ // case 0x43: // INSTANCEOF
+ // case 0x44: // NEW
+ // case 0x45: // CONSTRUCTOR_REFERENCE
+ // case 0x46: // METHOD_REFERENCE
+ default:
+ out.put12(typeRef >>> 24, (typeRef & 0xFFFF00) >> 8);
+ break;
+ }
+ if (typePath == null) {
+ out.putByte(0);
+ } else {
+ int length = typePath.b[typePath.offset] * 2 + 1;
+ out.putByteArray(typePath.b, typePath.offset, length);
+ }
+ }
}
diff --git a/parabotv2/src/org/objectweb/asm/Attribute.java b/parabotv2/src/org/objectweb/asm/Attribute.java
index 868e1ff..8a2a882 100644
--- a/parabotv2/src/org/objectweb/asm/Attribute.java
+++ b/parabotv2/src/org/objectweb/asm/Attribute.java
@@ -93,7 +93,7 @@ public class Attribute {
/**
* Reads a {@link #type type} attribute. This method must return a
- * new {@link org.objectweb.asm.Attribute} object, of type {@link #type type},
+ * new {@link Attribute} object, of type {@link #type type},
* corresponding to the len bytes starting at the given offset, in
* the given class reader.
*
@@ -119,7 +119,7 @@ public class Attribute {
* @param labels
* the labels of the method's code, or null if the
* attribute to be read is not a code attribute.
- * @return a new {@link org.objectweb.asm.Attribute} object corresponding to the given
+ * @return a new {@link Attribute} object corresponding to the given
* bytes.
*/
protected Attribute read(final ClassReader cr, final int off,
diff --git a/parabotv2/src/org/objectweb/asm/ByteVector.java b/parabotv2/src/org/objectweb/asm/ByteVector.java
index 579d7d4..f1e2da1 100644
--- a/parabotv2/src/org/objectweb/asm/ByteVector.java
+++ b/parabotv2/src/org/objectweb/asm/ByteVector.java
@@ -48,7 +48,7 @@ public class ByteVector {
int length;
/**
- * Constructs a new {@link org.objectweb.asm.ByteVector ByteVector} with a default initial
+ * Constructs a new {@link ByteVector ByteVector} with a default initial
* size.
*/
public ByteVector() {
@@ -56,7 +56,7 @@ public class ByteVector {
}
/**
- * Constructs a new {@link org.objectweb.asm.ByteVector ByteVector} with the given initial
+ * Constructs a new {@link ByteVector ByteVector} with the given initial
* size.
*
* @param initialSize
@@ -204,11 +204,14 @@ public class ByteVector {
* automatically enlarged if necessary.
*
* @param s
- * a String.
+ * a String whose UTF8 encoded length must be less than 65536.
* @return this byte vector.
*/
public ByteVector putUTF8(final String s) {
int charLength = s.length();
+ if (charLength > 65535) {
+ throw new IllegalArgumentException();
+ }
int len = length;
if (len + 2 + charLength > data.length) {
enlarge(2 + charLength);
@@ -238,6 +241,9 @@ public class ByteVector {
byteLength += 2;
}
}
+ if (byteLength > 65535) {
+ throw new IllegalArgumentException();
+ }
data[length] = (byte) (byteLength >>> 8);
data[length + 1] = (byte) byteLength;
if (length + 2 + byteLength > data.length) {
diff --git a/parabotv2/src/org/objectweb/asm/ClassReader.java b/parabotv2/src/org/objectweb/asm/ClassReader.java
index 35a6893..9816c60 100644
--- a/parabotv2/src/org/objectweb/asm/ClassReader.java
+++ b/parabotv2/src/org/objectweb/asm/ClassReader.java
@@ -106,7 +106,7 @@ public class ClassReader {
/**
* The class to be parsed. The content of this array must not be
- * modified. This field is intended for {@link org.objectweb.asm.Attribute} sub classes, and
+ * modified. This field is intended for {@link Attribute} sub classes, and
* is normally not needed by class generators or adapters.
*/
public final byte[] b;
@@ -144,7 +144,7 @@ public class ClassReader {
// ------------------------------------------------------------------------
/**
- * Constructs a new {@link org.objectweb.asm.ClassReader} object.
+ * Constructs a new {@link ClassReader} object.
*
* @param b
* the bytecode of the class to be read.
@@ -154,7 +154,7 @@ public class ClassReader {
}
/**
- * Constructs a new {@link org.objectweb.asm.ClassReader} object.
+ * Constructs a new {@link ClassReader} object.
*
* @param b
* the bytecode of the class to be read.
@@ -166,7 +166,7 @@ public class ClassReader {
public ClassReader(final byte[] b, final int off, final int len) {
this.b = b;
// checks the class version
- if (readShort(off + 6) > Opcodes.V1_7) {
+ if (readShort(off + 6) > Opcodes.V1_8) {
throw new IllegalArgumentException();
}
// parses the constant pool
@@ -413,11 +413,11 @@ public class ClassReader {
}
/**
- * Constructs a new {@link org.objectweb.asm.ClassReader} object.
+ * Constructs a new {@link ClassReader} object.
*
* @param is
* an input stream from which to read the class.
- * @throws java.io.IOException
+ * @throws IOException
* if a problem occurs during reading.
*/
public ClassReader(final InputStream is) throws IOException {
@@ -425,11 +425,11 @@ public class ClassReader {
}
/**
- * Constructs a new {@link org.objectweb.asm.ClassReader} object.
+ * Constructs a new {@link ClassReader} object.
*
* @param name
* the binary qualified name of the class to be read.
- * @throws java.io.IOException
+ * @throws IOException
* if an exception occurs during reading.
*/
public ClassReader(final String name) throws IOException {
@@ -446,7 +446,7 @@ public class ClassReader {
* @param close
* true to close the input stream after reading.
* @return the bytecode read from the given input stream.
- * @throws java.io.IOException
+ * @throws IOException
* if a problem occurs during reading.
*/
private static byte[] readClass(final InputStream is, boolean close)
@@ -491,7 +491,7 @@ public class ClassReader {
// ------------------------------------------------------------------------
/**
- * Makes the given visitor visit the Java class of this {@link org.objectweb.asm.ClassReader}
+ * Makes the given visitor visit the Java class of this {@link ClassReader}
* . This class is the one specified in the constructor (see
* {@link #ClassReader(byte[]) ClassReader}).
*
@@ -507,7 +507,7 @@ public class ClassReader {
}
/**
- * Makes the given visitor visit the Java class of this {@link org.objectweb.asm.ClassReader}.
+ * Makes the given visitor visit the Java class of this {@link ClassReader}.
* This class is the one specified in the constructor (see
* {@link #ClassReader(byte[]) ClassReader}).
*
@@ -557,6 +557,8 @@ public class ClassReader {
String enclosingDesc = null;
int anns = 0;
int ianns = 0;
+ int tanns = 0;
+ int itanns = 0;
int innerClasses = 0;
Attribute attributes = null;
@@ -581,6 +583,9 @@ public class ClassReader {
} else if (ANNOTATIONS
&& "RuntimeVisibleAnnotations".equals(attrName)) {
anns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ tanns = u + 8;
} else if ("Deprecated".equals(attrName)) {
access |= Opcodes.ACC_DEPRECATED;
} else if ("Synthetic".equals(attrName)) {
@@ -592,6 +597,9 @@ public class ClassReader {
} else if (ANNOTATIONS
&& "RuntimeInvisibleAnnotations".equals(attrName)) {
ianns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ itanns = u + 8;
} else if ("BootstrapMethods".equals(attrName)) {
int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
@@ -626,7 +634,7 @@ public class ClassReader {
enclosingDesc);
}
- // visits the class annotations
+ // visits the class annotations and type annotations
if (ANNOTATIONS && anns != 0) {
for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
@@ -639,6 +647,22 @@ public class ClassReader {
classVisitor.visitAnnotation(readUTF8(v, c), false));
}
}
+ if (ANNOTATIONS && tanns != 0) {
+ for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
+ v = readAnnotationTarget(context, v);
+ v = readAnnotationValues(v + 2, c, true,
+ classVisitor.visitTypeAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), true));
+ }
+ }
+ if (ANNOTATIONS && itanns != 0) {
+ for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
+ v = readAnnotationTarget(context, v);
+ v = readAnnotationValues(v + 2, c, true,
+ classVisitor.visitTypeAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), false));
+ }
+ }
// visits the attributes
while (attributes != null) {
@@ -697,6 +721,8 @@ public class ClassReader {
String signature = null;
int anns = 0;
int ianns = 0;
+ int tanns = 0;
+ int itanns = 0;
Object value = null;
Attribute attributes = null;
@@ -717,9 +743,15 @@ public class ClassReader {
} else if (ANNOTATIONS
&& "RuntimeVisibleAnnotations".equals(attrName)) {
anns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ tanns = u + 8;
} else if (ANNOTATIONS
&& "RuntimeInvisibleAnnotations".equals(attrName)) {
ianns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ itanns = u + 8;
} else {
Attribute attr = readAttribute(context.attrs, attrName, u + 8,
readInt(u + 4), c, -1, null);
@@ -739,7 +771,7 @@ public class ClassReader {
return u;
}
- // visits the field annotations
+ // visits the field annotations and type annotations
if (ANNOTATIONS && anns != 0) {
for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
@@ -752,6 +784,22 @@ public class ClassReader {
fv.visitAnnotation(readUTF8(v, c), false));
}
}
+ if (ANNOTATIONS && tanns != 0) {
+ for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
+ v = readAnnotationTarget(context, v);
+ v = readAnnotationValues(v + 2, c, true,
+ fv.visitTypeAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), true));
+ }
+ }
+ if (ANNOTATIONS && itanns != 0) {
+ for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
+ v = readAnnotationTarget(context, v);
+ v = readAnnotationValues(v + 2, c, true,
+ fv.visitTypeAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), false));
+ }
+ }
// visits the field attributes
while (attributes != null) {
@@ -782,9 +830,9 @@ public class ClassReader {
final Context context, int u) {
// reads the method declaration
char[] c = context.buffer;
- int access = readUnsignedShort(u);
- String name = readUTF8(u + 2, c);
- String desc = readUTF8(u + 4, c);
+ context.access = readUnsignedShort(u);
+ context.name = readUTF8(u + 2, c);
+ context.desc = readUTF8(u + 4, c);
u += 6;
// reads the method attributes
@@ -792,8 +840,11 @@ public class ClassReader {
int exception = 0;
String[] exceptions = null;
String signature = null;
+ int methodParameters = 0;
int anns = 0;
int ianns = 0;
+ int tanns = 0;
+ int itanns = 0;
int dann = 0;
int mpanns = 0;
int impanns = 0;
@@ -818,24 +869,32 @@ public class ClassReader {
} else if (SIGNATURES && "Signature".equals(attrName)) {
signature = readUTF8(u + 8, c);
} else if ("Deprecated".equals(attrName)) {
- access |= Opcodes.ACC_DEPRECATED;
+ context.access |= Opcodes.ACC_DEPRECATED;
} else if (ANNOTATIONS
&& "RuntimeVisibleAnnotations".equals(attrName)) {
anns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ tanns = u + 8;
} else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
dann = u + 8;
} else if ("Synthetic".equals(attrName)) {
- access |= Opcodes.ACC_SYNTHETIC
+ context.access |= Opcodes.ACC_SYNTHETIC
| ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
} else if (ANNOTATIONS
&& "RuntimeInvisibleAnnotations".equals(attrName)) {
ianns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ itanns = u + 8;
} else if (ANNOTATIONS
&& "RuntimeVisibleParameterAnnotations".equals(attrName)) {
mpanns = u + 8;
} else if (ANNOTATIONS
&& "RuntimeInvisibleParameterAnnotations".equals(attrName)) {
impanns = u + 8;
+ } else if ("MethodParameters".equals(attrName)) {
+ methodParameters = u + 8;
} else {
Attribute attr = readAttribute(context.attrs, attrName, u + 8,
readInt(u + 4), c, -1, null);
@@ -849,8 +908,8 @@ public class ClassReader {
u += 2;
// visits the method declaration
- MethodVisitor mv = classVisitor.visitMethod(access, name, desc,
- signature, exceptions);
+ MethodVisitor mv = classVisitor.visitMethod(context.access,
+ context.name, context.desc, signature, exceptions);
if (mv == null) {
return u;
}
@@ -894,6 +953,13 @@ public class ClassReader {
}
}
+ // visit the method parameters
+ if (methodParameters != 0) {
+ for (int i = b[methodParameters] & 0xFF, v = methodParameters + 1; i > 0; --i, v = v + 4) {
+ mv.visitParameter(readUTF8(v, c), readUnsignedShort(v + 2));
+ }
+ }
+
// visits the method annotations
if (ANNOTATIONS && dann != 0) {
AnnotationVisitor dv = mv.visitAnnotationDefault();
@@ -914,11 +980,27 @@ public class ClassReader {
mv.visitAnnotation(readUTF8(v, c), false));
}
}
+ if (ANNOTATIONS && tanns != 0) {
+ for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
+ v = readAnnotationTarget(context, v);
+ v = readAnnotationValues(v + 2, c, true,
+ mv.visitTypeAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), true));
+ }
+ }
+ if (ANNOTATIONS && itanns != 0) {
+ for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
+ v = readAnnotationTarget(context, v);
+ v = readAnnotationValues(v + 2, c, true,
+ mv.visitTypeAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), false));
+ }
+ }
if (ANNOTATIONS && mpanns != 0) {
- readParameterAnnotations(mpanns, desc, c, true, mv);
+ readParameterAnnotations(mv, context, mpanns, true);
}
if (ANNOTATIONS && impanns != 0) {
- readParameterAnnotations(impanns, desc, c, false, mv);
+ readParameterAnnotations(mv, context, impanns, false);
}
// visits the method attributes
@@ -931,9 +1013,6 @@ public class ClassReader {
// visits the method code
if (code != 0) {
- context.access = access;
- context.name = name;
- context.desc = desc;
mv.visitCode();
readCode(mv, context, code);
}
@@ -966,7 +1045,7 @@ public class ClassReader {
// reads the bytecode to find the labels
int codeStart = u;
int codeEnd = u + codeLength;
- Label[] labels = new Label[codeLength + 2];
+ Label[] labels = context.labels = new Label[codeLength + 2];
readLabel(codeLength + 1, labels);
while (u < codeEnd) {
int offset = u - codeStart;
@@ -1049,6 +1128,12 @@ public class ClassReader {
u += 2;
// reads the code attributes
+ int[] tanns = null; // start index of each visible type annotation
+ int[] itanns = null; // start index of each invisible type annotation
+ int tann = 0; // current index in tanns array
+ int itann = 0; // current index in itanns array
+ int ntoff = -1; // next visible type annotation code offset
+ int nitoff = -1; // next invisible type annotation code offset
int varTable = 0;
int varTypeTable = 0;
boolean zip = true;
@@ -1089,6 +1174,16 @@ public class ClassReader {
v += 4;
}
}
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ tanns = readTypeAnnotations(mv, context, u + 8, true);
+ ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1
+ : readUnsignedShort(tanns[0] + 1);
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ itanns = readTypeAnnotations(mv, context, u + 8, false);
+ nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1
+ : readUnsignedShort(itanns[0] + 1);
} else if (FRAMES && "StackMapTable".equals(attrName)) {
if ((context.flags & SKIP_FRAMES) == 0) {
stackMap = u + 10;
@@ -1211,7 +1306,7 @@ public class ClassReader {
}
}
if (frameCount > 0) {
- stackMap = readFrame(stackMap, zip, unzip, labels, frame);
+ stackMap = readFrame(stackMap, zip, unzip, frame);
--frameCount;
} else {
frame = null;
@@ -1358,6 +1453,29 @@ public class ClassReader {
u += 4;
break;
}
+
+ // visit the instruction annotations, if any
+ while (tanns != null && tann < tanns.length && ntoff <= offset) {
+ if (ntoff == offset) {
+ int v = readAnnotationTarget(context, tanns[tann]);
+ readAnnotationValues(v + 2, c, true,
+ mv.visitInsnAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), true));
+ }
+ ntoff = ++tann >= tanns.length || readByte(tanns[tann]) < 0x43 ? -1
+ : readUnsignedShort(tanns[tann] + 1);
+ }
+ while (itanns != null && itann < itanns.length && nitoff <= offset) {
+ if (nitoff == offset) {
+ int v = readAnnotationTarget(context, itanns[itann]);
+ readAnnotationValues(v + 2, c, true,
+ mv.visitInsnAnnotation(context.typeRef,
+ context.typePath, readUTF8(v, c), false));
+ }
+ nitoff = ++itann >= itanns.length
+ || readByte(itanns[itann]) < 0x43 ? -1
+ : readUnsignedShort(itanns[itann] + 1);
+ }
}
if (labels[codeLength] != null) {
mv.visitLabel(labels[codeLength]);
@@ -1397,6 +1515,32 @@ public class ClassReader {
}
}
+ // visits the local variables type annotations
+ if (tanns != null) {
+ for (int i = 0; i < tanns.length; ++i) {
+ if ((readByte(tanns[i]) >> 1) == (0x40 >> 1)) {
+ int v = readAnnotationTarget(context, tanns[i]);
+ v = readAnnotationValues(v + 2, c, true,
+ mv.visitLocalVariableAnnotation(context.typeRef,
+ context.typePath, context.start,
+ context.end, context.index, readUTF8(v, c),
+ true));
+ }
+ }
+ }
+ if (itanns != null) {
+ for (int i = 0; i < itanns.length; ++i) {
+ if ((readByte(itanns[i]) >> 1) == (0x40 >> 1)) {
+ int v = readAnnotationTarget(context, itanns[i]);
+ v = readAnnotationValues(v + 2, c, true,
+ mv.visitLocalVariableAnnotation(context.typeRef,
+ context.typePath, context.start,
+ context.end, context.index, readUTF8(v, c),
+ false));
+ }
+ }
+ }
+
// visits the code attributes
while (attributes != null) {
Attribute attr = attributes.next;
@@ -1409,25 +1553,176 @@ public class ClassReader {
mv.visitMaxs(maxStack, maxLocals);
}
+ /**
+ * Parses a type annotation table to find the labels, and to visit the try
+ * catch block annotations.
+ *
+ * @param u
+ * the start offset of a type annotation table.
+ * @param mv
+ * the method visitor to be used to visit the try catch block
+ * annotations.
+ * @param context
+ * information about the class being parsed.
+ * @param visible
+ * if the type annotation table to parse contains runtime visible
+ * annotations.
+ * @return the start offset of each type annotation in the parsed table.
+ */
+ private int[] readTypeAnnotations(final MethodVisitor mv,
+ final Context context, int u, boolean visible) {
+ char[] c = context.buffer;
+ int[] offsets = new int[readUnsignedShort(u)];
+ u += 2;
+ for (int i = 0; i < offsets.length; ++i) {
+ offsets[i] = u;
+ int target = readInt(u);
+ switch (target >>> 24) {
+ case 0x00: // CLASS_TYPE_PARAMETER
+ case 0x01: // METHOD_TYPE_PARAMETER
+ case 0x16: // METHOD_FORMAL_PARAMETER
+ u += 2;
+ break;
+ case 0x13: // FIELD
+ case 0x14: // METHOD_RETURN
+ case 0x15: // METHOD_RECEIVER
+ u += 1;
+ break;
+ case 0x40: // LOCAL_VARIABLE
+ case 0x41: // RESOURCE_VARIABLE
+ for (int j = readUnsignedShort(u + 1); j > 0; --j) {
+ int start = readUnsignedShort(u + 3);
+ int length = readUnsignedShort(u + 5);
+ readLabel(start, context.labels);
+ readLabel(start + length, context.labels);
+ u += 6;
+ }
+ u += 3;
+ break;
+ case 0x47: // CAST
+ case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+ case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
+ case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+ case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
+ u += 4;
+ break;
+ // case 0x10: // CLASS_EXTENDS
+ // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
+ // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
+ // case 0x17: // THROWS
+ // case 0x42: // EXCEPTION_PARAMETER
+ // case 0x43: // INSTANCEOF
+ // case 0x44: // NEW
+ // case 0x45: // CONSTRUCTOR_REFERENCE
+ // case 0x46: // METHOD_REFERENCE
+ default:
+ u += 3;
+ break;
+ }
+ int pathLength = readByte(u);
+ if ((target >>> 24) == 0x42) {
+ TypePath path = pathLength == 0 ? null : new TypePath(b, u);
+ u += 1 + 2 * pathLength;
+ u = readAnnotationValues(u + 2, c, true,
+ mv.visitTryCatchAnnotation(target, path,
+ readUTF8(u, c), visible));
+ } else {
+ u = readAnnotationValues(u + 3 + 2 * pathLength, c, true, null);
+ }
+ }
+ return offsets;
+ }
+
+ /**
+ * Parses the header of a type annotation to extract its target_type and
+ * target_path (the result is stored in the given context), and returns the
+ * start offset of the rest of the type_annotation structure (i.e. the
+ * offset to the type_index field, which is followed by
+ * num_element_value_pairs and then the name,value pairs).
+ *
+ * @param context
+ * information about the class being parsed. This is where the
+ * extracted target_type and target_path must be stored.
+ * @param u
+ * the start offset of a type_annotation structure.
+ * @return the start offset of the rest of the type_annotation structure.
+ */
+ private int readAnnotationTarget(final Context context, int u) {
+ int target = readInt(u);
+ switch (target >>> 24) {
+ case 0x00: // CLASS_TYPE_PARAMETER
+ case 0x01: // METHOD_TYPE_PARAMETER
+ case 0x16: // METHOD_FORMAL_PARAMETER
+ target &= 0xFFFF0000;
+ u += 2;
+ break;
+ case 0x13: // FIELD
+ case 0x14: // METHOD_RETURN
+ case 0x15: // METHOD_RECEIVER
+ target &= 0xFF000000;
+ u += 1;
+ break;
+ case 0x40: // LOCAL_VARIABLE
+ case 0x41: { // RESOURCE_VARIABLE
+ target &= 0xFF000000;
+ int n = readUnsignedShort(u + 1);
+ context.start = new Label[n];
+ context.end = new Label[n];
+ context.index = new int[n];
+ u += 3;
+ for (int i = 0; i < n; ++i) {
+ int start = readUnsignedShort(u);
+ int length = readUnsignedShort(u + 2);
+ context.start[i] = readLabel(start, context.labels);
+ context.end[i] = readLabel(start + length, context.labels);
+ context.index[i] = readUnsignedShort(u + 4);
+ u += 6;
+ }
+ break;
+ }
+ case 0x47: // CAST
+ case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+ case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
+ case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+ case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
+ target &= 0xFF0000FF;
+ u += 4;
+ break;
+ // case 0x10: // CLASS_EXTENDS
+ // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
+ // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
+ // case 0x17: // THROWS
+ // case 0x42: // EXCEPTION_PARAMETER
+ // case 0x43: // INSTANCEOF
+ // case 0x44: // NEW
+ // case 0x45: // CONSTRUCTOR_REFERENCE
+ // case 0x46: // METHOD_REFERENCE
+ default:
+ target &= (target >>> 24) < 0x43 ? 0xFFFFFF00 : 0xFF000000;
+ u += 3;
+ break;
+ }
+ int pathLength = readByte(u);
+ context.typeRef = target;
+ context.typePath = pathLength == 0 ? null : new TypePath(b, u);
+ return u + 1 + 2 * pathLength;
+ }
+
/**
* Reads parameter annotations and makes the given visitor visit them.
*
+ * @param mv
+ * the visitor that must visit the annotations.
+ * @param context
+ * information about the class being parsed.
* @param v
* start offset in {@link #b b} of the annotations to be read.
- * @param desc
- * the method descriptor.
- * @param buf
- * buffer to be used to call {@link #readUTF8 readUTF8},
- * {@link #readClass(int,char[]) readClass} or {@link #readConst
- * readConst}.
* @param visible
* true if the annotations to be read are visible at
* runtime.
- * @param mv
- * the visitor that must visit the annotations.
*/
- private void readParameterAnnotations(int v, final String desc,
- final char[] buf, final boolean visible, final MethodVisitor mv) {
+ private void readParameterAnnotations(final MethodVisitor mv,
+ final Context context, int v, final boolean visible) {
int i;
int n = b[v++] & 0xFF;
// workaround for a bug in javac (javac compiler generates a parameter
@@ -1436,7 +1731,7 @@ public class ClassReader {
// equal to the number of parameters in the method descriptor - which
// includes the synthetic parameters added by the compiler). This work-
// around supposes that the synthetic parameters are the first ones.
- int synthetics = Type.getArgumentTypes(desc).length - n;
+ int synthetics = Type.getArgumentTypes(context.desc).length - n;
AnnotationVisitor av;
for (i = 0; i < synthetics; ++i) {
// virtual annotation to detect synthetic parameters in MethodWriter
@@ -1445,12 +1740,13 @@ public class ClassReader {
av.visitEnd();
}
}
+ char[] c = context.buffer;
for (; i < n + synthetics; ++i) {
int j = readUnsignedShort(v);
v += 2;
for (; j > 0; --j) {
- av = mv.visitParameterAnnotation(i, readUTF8(v, buf), visible);
- v = readAnnotationValues(v + 2, buf, true, av);
+ av = mv.visitParameterAnnotation(i, readUTF8(v, c), visible);
+ v = readAnnotationValues(v + 2, c, true, av);
}
}
}
@@ -1729,17 +2025,14 @@ public class ClassReader {
* if the stack map frame at stackMap is compressed or not.
* @param unzip
* if the stack map frame must be uncompressed.
- * @param labels
- * the labels of the method currently being parsed, indexed by
- * their offset. A new label for the parsed stack map frame is
- * stored in this array if it does not already exist.
* @param frame
* where the parsed stack map frame must be stored.
* @return the offset of the first byte following the parsed frame.
*/
private int readFrame(int stackMap, boolean zip, boolean unzip,
- Label[] labels, Context frame) {
+ Context frame) {
char[] c = frame.buffer;
+ Label[] labels = frame.labels;
int tag;
int delta;
if (zip) {
@@ -1916,7 +2209,7 @@ public class ClassReader {
* prototypes of the attributes that must be parsed during the
* visit of the class. Any attribute whose type is not equal to
* the type of one the prototypes is ignored (i.e. an empty
- * {@link org.objectweb.asm.Attribute} instance is returned).
+ * {@link Attribute} instance is returned).
* @param type
* the type of the attribute.
* @param off
@@ -1968,7 +2261,7 @@ public class ClassReader {
/**
* Returns the start index of the constant pool item in {@link #b b}, plus
- * one. This method is intended for {@link org.objectweb.asm.Attribute} sub classes, and is
+ * one. This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
*
* @param item
@@ -1993,7 +2286,7 @@ public class ClassReader {
/**
* Reads a byte value in {@link #b b}. This method is intended for
- * {@link org.objectweb.asm.Attribute} sub classes, and is normally not needed by class
+ * {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.
*
* @param index
@@ -2006,7 +2299,7 @@ public class ClassReader {
/**
* Reads an unsigned short value in {@link #b b}. This method is intended
- * for {@link org.objectweb.asm.Attribute} sub classes, and is normally not needed by class
+ * for {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.
*
* @param index
@@ -2020,7 +2313,7 @@ public class ClassReader {
/**
* Reads a signed short value in {@link #b b}. This method is intended
- * for {@link org.objectweb.asm.Attribute} sub classes, and is normally not needed by class
+ * for {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.
*
* @param index
@@ -2034,7 +2327,7 @@ public class ClassReader {
/**
* Reads a signed int value in {@link #b b}. This method is intended for
- * {@link org.objectweb.asm.Attribute} sub classes, and is normally not needed by class
+ * {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.
*
* @param index
@@ -2049,7 +2342,7 @@ public class ClassReader {
/**
* Reads a signed long value in {@link #b b}. This method is intended for
- * {@link org.objectweb.asm.Attribute} sub classes, and is normally not needed by class
+ * {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.
*
* @param index
@@ -2064,7 +2357,7 @@ public class ClassReader {
/**
* Reads an UTF8 string constant pool item in {@link #b b}. This method
- * is intended for {@link org.objectweb.asm.Attribute} sub classes, and is normally not needed
+ * is intended for {@link Attribute} sub classes, and is normally not needed
* by class generators or adapters.
*
* @param index
@@ -2139,7 +2432,7 @@ public class ClassReader {
/**
* Reads a class constant pool item in {@link #b b}. This method is
- * intended for {@link org.objectweb.asm.Attribute} sub classes, and is normally not needed by
+ * intended for {@link Attribute} sub classes, and is normally not needed by
* class generators or adapters.
*
* @param index
@@ -2159,7 +2452,7 @@ public class ClassReader {
/**
* Reads a numeric or string constant pool item in {@link #b b}. This
- * method is intended for {@link org.objectweb.asm.Attribute} sub classes, and is normally not
+ * method is intended for {@link Attribute} sub classes, and is normally not
* needed by class generators or adapters.
*
* @param item
diff --git a/parabotv2/src/org/objectweb/asm/ClassVisitor.java b/parabotv2/src/org/objectweb/asm/ClassVisitor.java
index 57b0514..107ada0 100644
--- a/parabotv2/src/org/objectweb/asm/ClassVisitor.java
+++ b/parabotv2/src/org/objectweb/asm/ClassVisitor.java
@@ -33,8 +33,9 @@ package org.objectweb.asm;
* A visitor to visit a Java class. The methods of this class must be called in
* the following order: visit [ visitSource ] [
* visitOuterClass ] ( visitAnnotation |
- * visitAttribute )* ( visitInnerClass | visitField |
- * visitMethod )* visitEnd.
+ * visitTypeAnnotation | visitAttribute )* (
+ * visitInnerClass | visitField | visitMethod )*
+ * visitEnd.
*
* @author Eric Bruneton
*/
@@ -42,7 +43,7 @@ public abstract class ClassVisitor {
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4}.
+ * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
*/
protected final int api;
@@ -53,28 +54,28 @@ public abstract class ClassVisitor {
protected ClassVisitor cv;
/**
- * Constructs a new {@link org.objectweb.asm.ClassVisitor}.
+ * Constructs a new {@link ClassVisitor}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
*/
public ClassVisitor(final int api) {
this(api, null);
}
/**
- * Constructs a new {@link org.objectweb.asm.ClassVisitor}.
+ * Constructs a new {@link ClassVisitor}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
* @param cv
* the class visitor to which this visitor must delegate method
* calls. May be null.
*/
public ClassVisitor(final int api, final ClassVisitor cv) {
- if (api != Opcodes.ASM4) {
+ if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
throw new IllegalArgumentException();
}
this.api = api;
@@ -168,6 +169,39 @@ public abstract class ClassVisitor {
return null;
}
+ /**
+ * Visits an annotation on a type in the class signature.
+ *
+ * @param typeRef
+ * a reference to the annotated type. The sort of this type
+ * reference must be {@link TypeReference#CLASS_TYPE_PARAMETER
+ * CLASS_TYPE_PARAMETER},
+ * {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND
+ * CLASS_TYPE_PARAMETER_BOUND} or
+ * {@link TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. See
+ * {@link 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 a visitor to visit the annotation values, or null if
+ * this visitor is not interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new RuntimeException();
+ }
+ if (cv != null) {
+ return cv.visitTypeAnnotation(typeRef, typePath, desc, visible);
+ }
+ return null;
+ }
+
/**
* Visits a non standard attribute of the class.
*
diff --git a/parabotv2/src/org/objectweb/asm/ClassWriter.java b/parabotv2/src/org/objectweb/asm/ClassWriter.java
index 9a7819c..7a77614 100644
--- a/parabotv2/src/org/objectweb/asm/ClassWriter.java
+++ b/parabotv2/src/org/objectweb/asm/ClassWriter.java
@@ -30,10 +30,10 @@
package org.objectweb.asm;
/**
- * A {@link org.objectweb.asm.ClassVisitor} that generates classes in bytecode form. More
+ * A {@link ClassVisitor} that generates classes in bytecode form. More
* precisely this visitor generates a byte array conforming to the Java class
* file format. It can be used alone, to generate a Java class "from scratch",
- * or with one or more {@link org.objectweb.asm.ClassReader ClassReader} and adapter class visitor
+ * or with one or more {@link ClassReader ClassReader} and adapter class visitor
* to generate a modified class from one or more existing Java classes.
*
* @author Eric Bruneton
@@ -250,7 +250,7 @@ public class ClassWriter extends ClassVisitor {
static final int HANDLE_BASE = 20;
/**
- * Normal type Item stored in the ClassWriter {@link org.objectweb.asm.ClassWriter#typeTable},
+ * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable},
* instead of the constant pool, in order to avoid clashes with normal
* constant pool items in the ClassWriter constant pool's hash table.
*/
@@ -258,14 +258,14 @@ public class ClassWriter extends ClassVisitor {
/**
* Uninitialized type Item stored in the ClassWriter
- * {@link org.objectweb.asm.ClassWriter#typeTable}, instead of the constant pool, in order to
+ * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
* avoid clashes with normal constant pool items in the ClassWriter constant
* pool's hash table.
*/
static final int TYPE_UNINIT = 31;
/**
- * Merged type Item stored in the ClassWriter {@link org.objectweb.asm.ClassWriter#typeTable},
+ * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable},
* instead of the constant pool, in order to avoid clashes with normal
* constant pool items in the ClassWriter constant pool's hash table.
*/
@@ -416,6 +416,16 @@ public class ClassWriter extends ClassVisitor {
*/
private AnnotationWriter ianns;
+ /**
+ * The runtime visible type annotations of this class.
+ */
+ private AnnotationWriter tanns;
+
+ /**
+ * The runtime invisible type annotations of this class.
+ */
+ private AnnotationWriter itanns;
+
/**
* The non standard attributes of this class.
*/
@@ -477,12 +487,12 @@ public class ClassWriter extends ClassVisitor {
* true if the maximum stack size and number of local variables
* must be automatically computed.
*/
- private final boolean computeMaxs;
+ private boolean computeMaxs;
/**
* true if the stack map frames must be recomputed from scratch.
*/
- private final boolean computeFrames;
+ private boolean computeFrames;
/**
* true if the stack map tables of this class are invalid. The
@@ -587,7 +597,7 @@ public class ClassWriter extends ClassVisitor {
// ------------------------------------------------------------------------
/**
- * Constructs a new {@link org.objectweb.asm.ClassWriter} object.
+ * Constructs a new {@link ClassWriter} object.
*
* @param flags
* option flags that can be used to modify the default behavior
@@ -595,7 +605,7 @@ public class ClassWriter extends ClassVisitor {
* {@link #COMPUTE_FRAMES}.
*/
public ClassWriter(final int flags) {
- super(Opcodes.ASM4);
+ super(Opcodes.ASM5);
index = 1;
pool = new ByteVector();
items = new Item[256];
@@ -609,7 +619,7 @@ public class ClassWriter extends ClassVisitor {
}
/**
- * Constructs a new {@link org.objectweb.asm.ClassWriter} object and enables optimizations for
+ * Constructs a new {@link ClassWriter} object and enables optimizations for
* "mostly add" bytecode transformations. These optimizations are the
* following:
*
@@ -622,13 +632,13 @@ public class ClassWriter extends ClassVisitor {
* directly from the original class bytecode (i.e. without emitting visit
* events for all the method instructions), which saves a lot of
* time. Untransformed methods are detected by the fact that the
- * {@link org.objectweb.asm.ClassReader} receives {@link MethodVisitor} objects that come from
- * a {@link org.objectweb.asm.ClassWriter} (and not from any other {@link org.objectweb.asm.ClassVisitor}
+ * {@link ClassReader} receives {@link MethodVisitor} objects that come from
+ * a {@link ClassWriter} (and not from any other {@link ClassVisitor}
* instance).
*
*
* @param classReader
- * the {@link org.objectweb.asm.ClassReader} used to read the original class. It
+ * the {@link ClassReader} used to read the original class. It
* will be used to copy the entire constant pool from the
* original class and also to copy other fragments of original
* bytecode where applicable.
@@ -710,6 +720,29 @@ public class ClassWriter extends ClassVisitor {
return aw;
}
+ @Override
+ public final AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, final String desc, final boolean visible) {
+ if (!ClassReader.ANNOTATIONS) {
+ return null;
+ }
+ ByteVector bv = new ByteVector();
+ // write target_type and target_info
+ AnnotationWriter.putTarget(typeRef, typePath, bv);
+ // write type, and reserve space for values count
+ bv.putShort(newUTF8(desc)).putShort(0);
+ AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv,
+ bv.length - 2);
+ if (visible) {
+ aw.next = tanns;
+ tanns = aw;
+ } else {
+ aw.next = itanns;
+ itanns = aw;
+ }
+ return aw;
+ }
+
@Override
public final void visitAttribute(final Attribute attr) {
attr.next = attrs;
@@ -831,6 +864,16 @@ public class ClassWriter extends ClassVisitor {
size += 8 + ianns.getSize();
newUTF8("RuntimeInvisibleAnnotations");
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ ++attributeCount;
+ size += 8 + tanns.getSize();
+ newUTF8("RuntimeVisibleTypeAnnotations");
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ ++attributeCount;
+ size += 8 + itanns.getSize();
+ newUTF8("RuntimeInvisibleTypeAnnotations");
+ }
if (attrs != null) {
attributeCount += attrs.getCount();
size += attrs.getSize(this, null, 0, -1, -1);
@@ -904,13 +947,34 @@ public class ClassWriter extends ClassVisitor {
out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out);
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ out.putShort(newUTF8("RuntimeVisibleTypeAnnotations"));
+ tanns.put(out);
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations"));
+ itanns.put(out);
+ }
if (attrs != null) {
attrs.put(this, null, 0, -1, -1, out);
}
if (invalidFrames) {
- ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
- new ClassReader(out.data).accept(cw, ClassReader.SKIP_FRAMES);
- return cw.toByteArray();
+ anns = null;
+ ianns = null;
+ attrs = null;
+ innerClassesCount = 0;
+ innerClasses = null;
+ bootstrapMethodsCount = 0;
+ bootstrapMethods = null;
+ firstField = null;
+ lastField = null;
+ firstMethod = null;
+ lastMethod = null;
+ computeMaxs = false;
+ computeFrames = true;
+ invalidFrames = false;
+ new ClassReader(out.data).accept(this, ClassReader.SKIP_FRAMES);
+ return toByteArray();
}
return out.data;
}
@@ -978,7 +1042,7 @@ public class ClassWriter extends ClassVisitor {
/**
* Adds a number or string constant 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 org.objectweb.asm.Attribute} sub classes, and is
+ * This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
*
* @param cst
@@ -995,7 +1059,7 @@ public class ClassWriter extends ClassVisitor {
/**
* Adds an UTF8 string 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 org.objectweb.asm.Attribute} sub classes, and is normally not
+ * method is intended for {@link Attribute} sub classes, and is normally not
* needed by class generators or adapters.
*
* @param value
@@ -1016,7 +1080,7 @@ public class ClassWriter extends ClassVisitor {
/**
* Adds a class reference 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 org.objectweb.asm.Attribute} sub classes, and is
+ * This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
*
* @param value
@@ -1037,7 +1101,7 @@ public class ClassWriter extends ClassVisitor {
/**
* Adds a class reference 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 org.objectweb.asm.Attribute} sub classes, and is
+ * This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
*
* @param value
@@ -1051,7 +1115,7 @@ public class ClassWriter extends ClassVisitor {
/**
* Adds a method type reference 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 org.objectweb.asm.Attribute} sub classes, and is
+ * This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
*
* @param methodDesc
@@ -1072,7 +1136,7 @@ public class ClassWriter extends ClassVisitor {
/**
* Adds a method type reference 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 org.objectweb.asm.Attribute} sub classes, and is
+ * This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
*
* @param methodDesc
@@ -1087,7 +1151,7 @@ public class ClassWriter extends ClassVisitor {
/**
* 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 org.objectweb.asm.Attribute} sub classes, and is normally not needed by
+ * intended for {@link Attribute} sub classes, and is normally not needed by
* class generators or adapters.
*
* @param tag
@@ -1128,7 +1192,7 @@ public class ClassWriter extends ClassVisitor {
/**
* 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 org.objectweb.asm.Attribute} sub classes, and is normally not needed by
+ * intended for {@link Attribute} sub classes, and is normally not needed by
* class generators or adapters.
*
* @param tag
@@ -1156,7 +1220,7 @@ public class ClassWriter extends ClassVisitor {
/**
* Adds an invokedynamic reference 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 org.objectweb.asm.Attribute} sub classes, and is
+ * This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
*
* @param name
@@ -1240,7 +1304,7 @@ public class ClassWriter extends ClassVisitor {
/**
* Adds an invokedynamic reference 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 org.objectweb.asm.Attribute} sub classes, and is
+ * This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
*
* @param name
@@ -1286,7 +1350,7 @@ public class ClassWriter extends ClassVisitor {
/**
* Adds a field reference 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 org.objectweb.asm.Attribute} sub classes, and is
+ * This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
*
* @param owner
@@ -1331,7 +1395,7 @@ public class ClassWriter extends ClassVisitor {
/**
* Adds a method reference 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 org.objectweb.asm.Attribute} sub classes, and is
+ * This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.
*
* @param owner
@@ -1449,7 +1513,7 @@ public class ClassWriter extends ClassVisitor {
/**
* Adds a name and type 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 org.objectweb.asm.Attribute} sub classes, and is normally not
+ * method is intended for {@link Attribute} sub classes, and is normally not
* needed by class generators or adapters.
*
* @param name
@@ -1577,7 +1641,7 @@ public class ClassWriter extends ClassVisitor {
/**
* Returns the common super type of the two given types. The default
- * implementation of this method loads the two given classes and uses
+ * implementation of this method loads the two given classes and uses
* the java.lang.Class methods to find the common super class. It can be
* overridden to compute this common super type in other ways, in particular
* without actually loading any class, or to take into account the class
diff --git a/parabotv2/src/org/objectweb/asm/Context.java b/parabotv2/src/org/objectweb/asm/Context.java
index 280e1eb..363b34c 100644
--- a/parabotv2/src/org/objectweb/asm/Context.java
+++ b/parabotv2/src/org/objectweb/asm/Context.java
@@ -31,7 +31,7 @@
package org.objectweb.asm;
/**
- * Information about a class being parsed in a {@link org.objectweb.asm.ClassReader}.
+ * Information about a class being parsed in a {@link ClassReader}.
*
* @author Eric Bruneton
*/
@@ -43,7 +43,7 @@ class Context {
Attribute[] attrs;
/**
- * The {@link org.objectweb.asm.ClassReader} option flags for the parsing of this class.
+ * The {@link ClassReader} option flags for the parsing of this class.
*/
int flags;
@@ -72,11 +72,46 @@ class Context {
*/
String desc;
+ /**
+ * The label objects, indexed by bytecode offset, of the method currently
+ * being parsed (only bytecode offsets for which a label is needed have a
+ * non null associated Label object).
+ */
+ Label[] labels;
+
+ /**
+ * The target of the type annotation currently being parsed.
+ */
+ int typeRef;
+
+ /**
+ * The path of the type annotation currently being parsed.
+ */
+ TypePath typePath;
+
/**
* The offset of the latest stack map frame that has been parsed.
*/
int offset;
+ /**
+ * The labels corresponding to the start of the local variable ranges in the
+ * local variable type annotation currently being parsed.
+ */
+ Label[] start;
+
+ /**
+ * The labels corresponding to the end of the local variable ranges in the
+ * local variable type annotation currently being parsed.
+ */
+ Label[] end;
+
+ /**
+ * The local variable indices for each local variable range in the local
+ * variable type annotation currently being parsed.
+ */
+ int[] index;
+
/**
* The encoding of the latest stack map frame that has been parsed.
*/
diff --git a/parabotv2/src/org/objectweb/asm/Edge.java b/parabotv2/src/org/objectweb/asm/Edge.java
index 74b35a7..4e87cba 100644
--- a/parabotv2/src/org/objectweb/asm/Edge.java
+++ b/parabotv2/src/org/objectweb/asm/Edge.java
@@ -43,20 +43,20 @@ class Edge {
/**
* Denotes a control flow graph edge corresponding to an exception handler.
- * More precisely any {@link org.objectweb.asm.Edge} whose {@link #info} is strictly positive
+ * More precisely any {@link Edge} whose {@link #info} is strictly positive
* corresponds to an exception handler. The actual value of {@link #info} is
- * the index, in the {@link org.objectweb.asm.ClassWriter} type table, of the exception that
+ * the index, in the {@link ClassWriter} type table, of the exception that
* is catched.
*/
static final int EXCEPTION = 0x7FFFFFFF;
/**
* Information about this control flow graph edge. If
- * {@link org.objectweb.asm.ClassWriter#COMPUTE_MAXS} is used this field is the (relative)
+ * {@link ClassWriter#COMPUTE_MAXS} is used this field is the (relative)
* stack size in the basic block from which this edge originates. This size
* is equal to the stack size at the "jump" instruction to which this edge
* corresponds, relatively to the stack size at the beginning of the
- * originating basic block. If {@link org.objectweb.asm.ClassWriter#COMPUTE_FRAMES} is used,
+ * originating basic block. If {@link ClassWriter#COMPUTE_FRAMES} is used,
* this field is the kind of this control flow graph edge (i.e. NORMAL or
* EXCEPTION).
*/
diff --git a/parabotv2/src/org/objectweb/asm/FieldVisitor.java b/parabotv2/src/org/objectweb/asm/FieldVisitor.java
index bfb26b5..2372e4c 100644
--- a/parabotv2/src/org/objectweb/asm/FieldVisitor.java
+++ b/parabotv2/src/org/objectweb/asm/FieldVisitor.java
@@ -31,8 +31,8 @@ package org.objectweb.asm;
/**
* A visitor to visit a Java field. The methods of this class must be called in
- * the following order: ( visitAnnotation | visitAttribute )*
- * visitEnd.
+ * the following order: ( visitAnnotation |
+ * visitTypeAnnotation | visitAttribute )* visitEnd.
*
* @author Eric Bruneton
*/
@@ -40,7 +40,7 @@ public abstract class FieldVisitor {
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4}.
+ * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
*/
protected final int api;
@@ -51,28 +51,28 @@ public abstract class FieldVisitor {
protected FieldVisitor fv;
/**
- * Constructs a new {@link org.objectweb.asm.FieldVisitor}.
+ * Constructs a new {@link FieldVisitor}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
*/
public FieldVisitor(final int api) {
this(api, null);
}
/**
- * Constructs a new {@link org.objectweb.asm.FieldVisitor}.
+ * Constructs a new {@link FieldVisitor}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
* @param fv
* the field visitor to which this visitor must delegate method
* calls. May be null.
*/
public FieldVisitor(final int api, final FieldVisitor fv) {
- if (api != Opcodes.ASM4) {
+ if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
throw new IllegalArgumentException();
}
this.api = api;
@@ -96,6 +96,35 @@ public abstract class FieldVisitor {
return null;
}
+ /**
+ * Visits an annotation on the type of the field.
+ *
+ * @param typeRef
+ * a reference to the annotated type. The sort of this type
+ * reference must be {@link TypeReference#FIELD FIELD}. See
+ * {@link 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 a visitor to visit the annotation values, or null if
+ * this visitor is not interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new RuntimeException();
+ }
+ if (fv != null) {
+ return fv.visitTypeAnnotation(typeRef, typePath, desc, visible);
+ }
+ return null;
+ }
+
/**
* Visits a non standard attribute of the field.
*
diff --git a/parabotv2/src/org/objectweb/asm/FieldWriter.java b/parabotv2/src/org/objectweb/asm/FieldWriter.java
index 86a58e6..84d92aa 100644
--- a/parabotv2/src/org/objectweb/asm/FieldWriter.java
+++ b/parabotv2/src/org/objectweb/asm/FieldWriter.java
@@ -30,7 +30,7 @@
package org.objectweb.asm;
/**
- * An {@link org.objectweb.asm.FieldVisitor} that generates Java fields in bytecode form.
+ * An {@link FieldVisitor} that generates Java fields in bytecode form.
*
* @author Eric Bruneton
*/
@@ -80,6 +80,17 @@ final class FieldWriter extends FieldVisitor {
*/
private AnnotationWriter ianns;
+ /**
+ * The runtime visible type annotations of this field. May be null.
+ */
+ private AnnotationWriter tanns;
+
+ /**
+ * The runtime invisible type annotations of this field. May be
+ * null.
+ */
+ private AnnotationWriter itanns;
+
/**
* The non standard attributes of this field. May be null.
*/
@@ -90,7 +101,7 @@ final class FieldWriter extends FieldVisitor {
// ------------------------------------------------------------------------
/**
- * Constructs a new {@link org.objectweb.asm.FieldWriter}.
+ * Constructs a new {@link FieldWriter}.
*
* @param cw
* the class writer to which this field must be added.
@@ -107,7 +118,7 @@ final class FieldWriter extends FieldVisitor {
*/
FieldWriter(final ClassWriter cw, final int access, final String name,
final String desc, final String signature, final Object value) {
- super(Opcodes.ASM4);
+ super(Opcodes.ASM5);
if (cw.firstField == null) {
cw.firstField = this;
} else {
@@ -150,6 +161,29 @@ final class FieldWriter extends FieldVisitor {
return aw;
}
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(final int typeRef,
+ final TypePath typePath, final String desc, final boolean visible) {
+ if (!ClassReader.ANNOTATIONS) {
+ return null;
+ }
+ ByteVector bv = new ByteVector();
+ // write target_type and target_info
+ AnnotationWriter.putTarget(typeRef, typePath, bv);
+ // write type, and reserve space for values count
+ bv.putShort(cw.newUTF8(desc)).putShort(0);
+ AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+ bv.length - 2);
+ if (visible) {
+ aw.next = tanns;
+ tanns = aw;
+ } else {
+ aw.next = itanns;
+ itanns = aw;
+ }
+ return aw;
+ }
+
@Override
public void visitAttribute(final Attribute attr) {
attr.next = attrs;
@@ -198,6 +232,14 @@ final class FieldWriter extends FieldVisitor {
cw.newUTF8("RuntimeInvisibleAnnotations");
size += 8 + ianns.getSize();
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ cw.newUTF8("RuntimeVisibleTypeAnnotations");
+ size += 8 + tanns.getSize();
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ cw.newUTF8("RuntimeInvisibleTypeAnnotations");
+ size += 8 + itanns.getSize();
+ }
if (attrs != null) {
size += attrs.getSize(cw, null, 0, -1, -1);
}
@@ -237,6 +279,12 @@ final class FieldWriter extends FieldVisitor {
if (ClassReader.ANNOTATIONS && ianns != null) {
++attributeCount;
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ ++attributeCount;
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ ++attributeCount;
+ }
if (attrs != null) {
attributeCount += attrs.getCount();
}
@@ -266,6 +314,14 @@ final class FieldWriter extends FieldVisitor {
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out);
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
+ tanns.put(out);
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
+ itanns.put(out);
+ }
if (attrs != null) {
attrs.put(cw, null, 0, -1, -1, out);
}
diff --git a/parabotv2/src/org/objectweb/asm/Frame.java b/parabotv2/src/org/objectweb/asm/Frame.java
index 507705b..10e15bc 100644
--- a/parabotv2/src/org/objectweb/asm/Frame.java
+++ b/parabotv2/src/org/objectweb/asm/Frame.java
@@ -1278,8 +1278,8 @@ final class Frame {
* @param frame
* the basic block whose input frame must be updated.
* @param edge
- * the kind of the {@link org.objectweb.asm.Edge} between this label and 'label'.
- * See {@link org.objectweb.asm.Edge#info}.
+ * the kind of the {@link Edge} between this label and 'label'.
+ * See {@link Edge#info}.
* @return true if the input frame of the given label has been
* changed by this operation.
*/
diff --git a/parabotv2/src/org/objectweb/asm/Handle.java b/parabotv2/src/org/objectweb/asm/Handle.java
index 533471e..a627911 100644
--- a/parabotv2/src/org/objectweb/asm/Handle.java
+++ b/parabotv2/src/org/objectweb/asm/Handle.java
@@ -49,7 +49,8 @@ public final class Handle {
final int tag;
/**
- * The internal name of the field or method designed by this handle.
+ * The internal name of the class that owns the field or method designated
+ * by this handle.
*/
final String owner;
@@ -76,8 +77,8 @@ public final class Handle {
* {@link Opcodes#H_NEWINVOKESPECIAL} or
* {@link Opcodes#H_INVOKEINTERFACE}.
* @param owner
- * the internal name of the field or method designed by this
- * handle.
+ * 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
@@ -106,9 +107,11 @@ public final class Handle {
}
/**
- * Returns the internal name of the field or method designed by this handle.
+ * Returns the internal name of the class that owns the field or method
+ * designated by this handle.
*
- * @return the internal name of the field or method designed by this handle.
+ * @return the internal name of the class that owns the field or method
+ * designated by this handle.
*/
public String getOwner() {
return owner;
diff --git a/parabotv2/src/org/objectweb/asm/Item.java b/parabotv2/src/org/objectweb/asm/Item.java
index 742173c..c25b7b7 100644
--- a/parabotv2/src/org/objectweb/asm/Item.java
+++ b/parabotv2/src/org/objectweb/asm/Item.java
@@ -31,7 +31,7 @@ package org.objectweb.asm;
/**
* A constant pool item. Constant pool items can be created with the 'newXXX'
- * methods in the {@link org.objectweb.asm.ClassWriter} class.
+ * methods in the {@link ClassWriter} class.
*
* @author Eric Bruneton
*/
@@ -45,24 +45,24 @@ final class Item {
/**
* Type of this constant pool item. A single class is used to represent all
* constant pool item types, in order to minimize the bytecode size of this
- * package. The value of this field is one of {@link org.objectweb.asm.ClassWriter#INT},
- * {@link org.objectweb.asm.ClassWriter#LONG}, {@link org.objectweb.asm.ClassWriter#FLOAT},
- * {@link org.objectweb.asm.ClassWriter#DOUBLE}, {@link org.objectweb.asm.ClassWriter#UTF8},
- * {@link org.objectweb.asm.ClassWriter#STR}, {@link org.objectweb.asm.ClassWriter#CLASS},
- * {@link org.objectweb.asm.ClassWriter#NAME_TYPE}, {@link org.objectweb.asm.ClassWriter#FIELD},
- * {@link org.objectweb.asm.ClassWriter#METH}, {@link org.objectweb.asm.ClassWriter#IMETH},
- * {@link org.objectweb.asm.ClassWriter#MTYPE}, {@link org.objectweb.asm.ClassWriter#INDY}.
+ * package. The value of this field is one of {@link ClassWriter#INT},
+ * {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT},
+ * {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8},
+ * {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
+ * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
+ * {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
+ * {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
*
* MethodHandle constant 9 variations are stored using a range of 9 values
- * from {@link org.objectweb.asm.ClassWriter#HANDLE_BASE} + 1 to
- * {@link org.objectweb.asm.ClassWriter#HANDLE_BASE} + 9.
+ * from {@link ClassWriter#HANDLE_BASE} + 1 to
+ * {@link ClassWriter#HANDLE_BASE} + 9.
*
* Special Item types are used for Items that are stored in the ClassWriter
- * {@link org.objectweb.asm.ClassWriter#typeTable}, instead of the constant pool, in order to
+ * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
* avoid clashes with normal constant pool items in the ClassWriter constant
* pool's hash table. These special item types are
- * {@link org.objectweb.asm.ClassWriter#TYPE_NORMAL}, {@link org.objectweb.asm.ClassWriter#TYPE_UNINIT} and
- * {@link org.objectweb.asm.ClassWriter#TYPE_MERGED}.
+ * {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and
+ * {@link ClassWriter#TYPE_MERGED}.
*/
int type;
@@ -106,13 +106,13 @@ final class Item {
Item next;
/**
- * Constructs an uninitialized {@link org.objectweb.asm.Item}.
+ * Constructs an uninitialized {@link Item}.
*/
Item() {
}
/**
- * Constructs an uninitialized {@link org.objectweb.asm.Item} for constant pool element at
+ * Constructs an uninitialized {@link Item} for constant pool element at
* given position.
*
* @param index
diff --git a/parabotv2/src/org/objectweb/asm/Label.java b/parabotv2/src/org/objectweb/asm/Label.java
index 3e7f894..1c4de30 100644
--- a/parabotv2/src/org/objectweb/asm/Label.java
+++ b/parabotv2/src/org/objectweb/asm/Label.java
@@ -214,7 +214,7 @@ public class Label {
/**
* Information about the input and output stack map frames of this basic
- * block. This field is only used when {@link org.objectweb.asm.ClassWriter#COMPUTE_FRAMES}
+ * block. This field is only used when {@link ClassWriter#COMPUTE_FRAMES}
* option is used.
*/
Frame frame;
@@ -222,7 +222,7 @@ public class Label {
/**
* The successor of this label, in the order they are visited. This linked
* list does not include labels used for debug info only. If
- * {@link org.objectweb.asm.ClassWriter#COMPUTE_FRAMES} option is used then, in addition, it
+ * {@link ClassWriter#COMPUTE_FRAMES} option is used then, in addition, it
* does not contain successive labels that denote the same bytecode position
* (in this case only the first label appears in this list).
*/
@@ -230,8 +230,8 @@ public class Label {
/**
* The successors of this node in the control flow graph. These successors
- * are stored in a linked list of {@link org.objectweb.asm.Edge Edge} objects, linked to each
- * other by their {@link org.objectweb.asm.Edge#next} field.
+ * are stored in a linked list of {@link Edge Edge} objects, linked to each
+ * other by their {@link Edge#next} field.
*/
Edge successors;
@@ -262,7 +262,7 @@ public class Label {
/**
* Returns the offset corresponding to this label. This offset is computed
* from the start of the method's bytecode. This method is intended for
- * {@link org.objectweb.asm.Attribute} sub classes, and is normally not needed by class
+ * {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.
*
* @return the offset corresponding to this label.
diff --git a/parabotv2/src/org/objectweb/asm/MethodVisitor.java b/parabotv2/src/org/objectweb/asm/MethodVisitor.java
index 1448177..832c124 100644
--- a/parabotv2/src/org/objectweb/asm/MethodVisitor.java
+++ b/parabotv2/src/org/objectweb/asm/MethodVisitor.java
@@ -31,18 +31,24 @@ package org.objectweb.asm;
/**
* A visitor to visit a Java method. The methods of this class must be called in
- * the following order: [ visitAnnotationDefault ] (
- * visitAnnotation | visitParameterAnnotation |
- * visitAttribute )* [ visitCode ( visitFrame |
- * visitXInsn | visitLabel |
- * visitTryCatchBlock | visitLocalVariable |
+ * the following order: ( visitParameter )* [
+ * visitAnnotationDefault ] ( visitAnnotation |
+ * visitTypeAnnotation | visitAttribute )* [
+ * visitCode ( visitFrame | visitXInsn |
+ * visitLabel | visitInsnAnnotation |
+ * visitTryCatchBlock | visitTryCatchBlockAnnotation |
+ * visitLocalVariable | visitLocalVariableAnnotation |
* visitLineNumber )* visitMaxs ] visitEnd. In
- * addition, the visitXInsn and visitLabel methods
- * must be called in the sequential order of the bytecode instructions of the
- * visited code, visitTryCatchBlock must be called before the
- * labels passed as arguments have been visited, and the
- * visitLocalVariable and visitLineNumber methods must be
- * called after the labels passed as arguments have been visited.
+ * addition, the visitXInsn and visitLabel methods must
+ * be called in the sequential order of the bytecode instructions of the visited
+ * code, visitInsnAnnotation must be called after the annotated
+ * instruction, visitTryCatchBlock must be called before the
+ * labels passed as arguments have been visited,
+ * visitTryCatchBlockAnnotation must be called after the
+ * corresponding try catch block has been visited, and the
+ * visitLocalVariable, visitLocalVariableAnnotation and
+ * visitLineNumber methods must be called after the labels
+ * passed as arguments have been visited.
*
* @author Eric Bruneton
*/
@@ -50,7 +56,7 @@ public abstract class MethodVisitor {
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4}.
+ * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
*/
protected final int api;
@@ -61,28 +67,28 @@ public abstract class MethodVisitor {
protected MethodVisitor mv;
/**
- * Constructs a new {@link org.objectweb.asm.MethodVisitor}.
+ * Constructs a new {@link MethodVisitor}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
*/
public MethodVisitor(final int api) {
this(api, null);
}
/**
- * Constructs a new {@link org.objectweb.asm.MethodVisitor}.
+ * Constructs a new {@link MethodVisitor}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
* @param mv
* the method visitor to which this visitor must delegate method
* calls. May be null.
*/
public MethodVisitor(final int api, final MethodVisitor mv) {
- if (api != Opcodes.ASM4) {
+ if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
throw new IllegalArgumentException();
}
this.api = api;
@@ -90,9 +96,28 @@ public abstract class MethodVisitor {
}
// -------------------------------------------------------------------------
- // Annotations and non standard attributes
+ // Parameters, annotations and non standard attributes
// -------------------------------------------------------------------------
+ /**
+ * Visits a parameter of this method.
+ *
+ * @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) {
+ if (api < Opcodes.ASM5) {
+ throw new RuntimeException();
+ }
+ if (mv != null) {
+ mv.visitParameter(name, access);
+ }
+ }
+
/**
* Visits the default value of this annotation interface method.
*
@@ -127,6 +152,42 @@ public abstract class MethodVisitor {
return null;
}
+ /**
+ * Visits an annotation on a type in the method signature.
+ *
+ * @param typeRef
+ * a reference to the annotated type. The sort of this type
+ * reference must be {@link TypeReference#METHOD_TYPE_PARAMETER
+ * METHOD_TYPE_PARAMETER},
+ * {@link TypeReference#METHOD_TYPE_PARAMETER_BOUND
+ * METHOD_TYPE_PARAMETER_BOUND},
+ * {@link TypeReference#METHOD_RETURN METHOD_RETURN},
+ * {@link TypeReference#METHOD_RECEIVER METHOD_RECEIVER},
+ * {@link TypeReference#METHOD_FORMAL_PARAMETER
+ * METHOD_FORMAL_PARAMETER} or {@link TypeReference#THROWS
+ * THROWS}. See {@link 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 a visitor to visit the annotation values, or null if
+ * this visitor is not interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new RuntimeException();
+ }
+ if (mv != null) {
+ return mv.visitTypeAnnotation(typeRef, typePath, desc, visible);
+ }
+ return null;
+ }
+
/**
* Visits an annotation of a parameter this method.
*
@@ -201,9 +262,11 @@ public abstract class MethodVisitor {
* nLocals is 1, 2 or 3).
+ *
+ *
+ *
* 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
@@ -395,7 +458,7 @@ public abstract class MethodVisitor {
* @param bsmArgs
* the bootstrap method constant arguments. Each argument must be
* an {@link Integer}, {@link Float}, {@link Long},
- * {@link Double}, {@link String}, {@link Type} or {@link org.objectweb.asm.Handle}
+ * {@link Double}, {@link String}, {@link 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.
*/
@@ -431,7 +494,7 @@ public abstract class MethodVisitor {
* just after it.
*
* @param label
- * a {@link org.objectweb.asm.Label Label} object.
+ * a {@link Label Label} object.
*/
public void visitLabel(Label label) {
if (mv != null) {
@@ -484,7 +547,7 @@ public abstract class MethodVisitor {
* {@link Double}, a {@link String}, a {@link Type} of OBJECT or
* ARRAY sort for .class constants, for classes whose
* version is 49.0, a {@link Type} of METHOD sort or a
- * {@link org.objectweb.asm.Handle} for MethodType and MethodHandle constants, for
+ * {@link Handle} for MethodType and MethodHandle constants, for
* classes whose version is 51.0.
*/
public void visitLdcInsn(Object cst) {
@@ -558,6 +621,48 @@ public abstract class MethodVisitor {
}
}
+ /**
+ * Visits an annotation on an instruction. This method must be called just
+ * after the annotated instruction. It can be called several times
+ * for the same instruction.
+ *
+ * @param typeRef
+ * a reference to the annotated type. The sort of this type
+ * reference must be {@link TypeReference#INSTANCEOF INSTANCEOF},
+ * {@link TypeReference#NEW NEW},
+ * {@link TypeReference#CONSTRUCTOR_REFERENCE
+ * CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE
+ * METHOD_REFERENCE}, {@link TypeReference#CAST CAST},
+ * {@link TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+ * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
+ * {@link TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT
+ * METHOD_INVOCATION_TYPE_ARGUMENT},
+ * {@link TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+ * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
+ * {@link TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT
+ * METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link 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 a visitor to visit the annotation values, or null if
+ * this visitor is not interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitInsnAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new RuntimeException();
+ }
+ if (mv != null) {
+ return mv.visitInsnAnnotation(typeRef, typePath, desc, visible);
+ }
+ return null;
+ }
+
// -------------------------------------------------------------------------
// Exceptions table entries, debug information, max stack and max locals
// -------------------------------------------------------------------------
@@ -586,6 +691,38 @@ public abstract class MethodVisitor {
}
}
+ /**
+ * Visits an annotation on an exception handler type. This method must be
+ * called after the {@link #visitTryCatchBlock} for the annotated
+ * exception handler. It can be called several times for the same exception
+ * handler.
+ *
+ * @param typeRef
+ * a reference to the annotated type. The sort of this type
+ * reference must be {@link TypeReference#EXCEPTION_PARAMETER
+ * EXCEPTION_PARAMETER}. See {@link 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 a visitor to visit the annotation values, or null if
+ * this visitor is not interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new RuntimeException();
+ }
+ if (mv != null) {
+ return mv.visitTryCatchAnnotation(typeRef, typePath, desc, visible);
+ }
+ return null;
+ }
+
/**
* Visits a local variable declaration.
*
@@ -616,6 +753,48 @@ public abstract class MethodVisitor {
}
}
+ /**
+ * Visits an annotation on a local variable type.
+ *
+ * @param typeRef
+ * a reference to the annotated type. The sort of this type
+ * reference must be {@link TypeReference#LOCAL_VARIABLE
+ * LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE
+ * RESOURCE_VARIABLE}. See {@link 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 a visitor to visit the annotation values, or null if
+ * this visitor is not interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+ TypePath typePath, Label[] start, Label[] end, int[] index,
+ String desc, boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new RuntimeException();
+ }
+ if (mv != null) {
+ return mv.visitLocalVariableAnnotation(typeRef, typePath, start,
+ end, index, desc, visible);
+ }
+ return null;
+ }
+
/**
* Visits a line number declaration.
*
diff --git a/parabotv2/src/org/objectweb/asm/MethodWriter.java b/parabotv2/src/org/objectweb/asm/MethodWriter.java
index cdc9a76..fd3c953 100644
--- a/parabotv2/src/org/objectweb/asm/MethodWriter.java
+++ b/parabotv2/src/org/objectweb/asm/MethodWriter.java
@@ -30,7 +30,7 @@
package org.objectweb.asm;
/**
- * A {@link org.objectweb.asm.MethodVisitor} that generates methods in bytecode form. Each visit
+ * A {@link MethodVisitor} that generates methods in bytecode form. Each visit
* method of this class appends the bytecode corresponding to the visited
* instruction to a byte vector, in the order these methods are called.
*
@@ -191,6 +191,18 @@ class MethodWriter extends MethodVisitor {
*/
private AnnotationWriter ianns;
+ /**
+ * The runtime visible type annotations of this method. May be null
+ * .
+ */
+ private AnnotationWriter tanns;
+
+ /**
+ * The runtime invisible type annotations of this method. May be
+ * null.
+ */
+ private AnnotationWriter itanns;
+
/**
* The runtime visible parameter annotations of this method. May be
* null.
@@ -263,7 +275,7 @@ class MethodWriter extends MethodVisitor {
* local variables start at index 3 and are followed by the operand stack
* values. In summary frame[0] = offset, frame[1] = nLocal, frame[2] =
* nStack, frame[3] = nLocal. All types are encoded as integers, with the
- * same format as the one used in {@link org.objectweb.asm.Label}, but limited to BASE types.
+ * same format as the one used in {@link Label}, but limited to BASE types.
*/
private int[] frame;
@@ -282,6 +294,16 @@ class MethodWriter extends MethodVisitor {
*/
private Handler lastHandler;
+ /**
+ * Number of entries in the MethodParameters attribute.
+ */
+ private int methodParametersCount;
+
+ /**
+ * The MethodParameters attribute.
+ */
+ private ByteVector methodParameters;
+
/**
* Number of entries in the LocalVariableTable attribute.
*/
@@ -312,6 +334,21 @@ class MethodWriter extends MethodVisitor {
*/
private ByteVector lineNumber;
+ /**
+ * The start offset of the last visited instruction.
+ */
+ private int lastCodeOffset;
+
+ /**
+ * The runtime visible type annotations of the code. May be null.
+ */
+ private AnnotationWriter ctanns;
+
+ /**
+ * The runtime invisible type annotations of the code. May be null.
+ */
+ private AnnotationWriter ictanns;
+
/**
* The non standard attributes of the method's code.
*/
@@ -351,8 +388,8 @@ class MethodWriter extends MethodVisitor {
/**
* A list of labels. This list is the list of basic blocks in the method,
* i.e. a list of Label objects linked to each other by their
- * {@link org.objectweb.asm.Label#successor} field, in the order they are visited by
- * {@link org.objectweb.asm.MethodVisitor#visitLabel}, and starting with the first basic
+ * {@link Label#successor} field, in the order they are visited by
+ * {@link MethodVisitor#visitLabel}, and starting with the first basic
* block.
*/
private Label labels;
@@ -371,7 +408,7 @@ class MethodWriter extends MethodVisitor {
* The (relative) stack size after the last visited instruction. This size
* is relative to the beginning of the current basic block, i.e., the true
* stack size after the last visited instruction is equal to the
- * {@link org.objectweb.asm.Label#inputStackTop beginStackSize} of the current basic block
+ * {@link Label#inputStackTop beginStackSize} of the current basic block
* plus stackSize.
*/
private int stackSize;
@@ -380,7 +417,7 @@ class MethodWriter extends MethodVisitor {
* The (relative) maximum stack size after the last visited instruction.
* This size is relative to the beginning of the current basic block, i.e.,
* the true maximum stack size after the last visited instruction is equal
- * to the {@link org.objectweb.asm.Label#inputStackTop beginStackSize} of the current basic
+ * to the {@link Label#inputStackTop beginStackSize} of the current basic
* block plus stackSize.
*/
private int maxStackSize;
@@ -390,7 +427,7 @@ class MethodWriter extends MethodVisitor {
// ------------------------------------------------------------------------
/**
- * Constructs a new {@link org.objectweb.asm.MethodWriter}.
+ * Constructs a new {@link MethodWriter}.
*
* @param cw
* the class writer in which the method must be added.
@@ -416,7 +453,7 @@ class MethodWriter extends MethodVisitor {
final String desc, final String signature,
final String[] exceptions, final boolean computeMaxs,
final boolean computeFrames) {
- super(Opcodes.ASM4);
+ super(Opcodes.ASM5);
if (cw.firstMethod == null) {
cw.firstMethod = this;
} else {
@@ -461,6 +498,16 @@ class MethodWriter extends MethodVisitor {
// Implementation of the MethodVisitor abstract class
// ------------------------------------------------------------------------
+ @Override
+ public void visitParameter(String name, int access) {
+ if (methodParameters == null) {
+ methodParameters = new ByteVector();
+ }
+ ++methodParametersCount;
+ methodParameters.putShort((name == null) ? 0 : cw.newUTF8(name))
+ .putShort(access);
+ }
+
@Override
public AnnotationVisitor visitAnnotationDefault() {
if (!ClassReader.ANNOTATIONS) {
@@ -490,6 +537,29 @@ class MethodWriter extends MethodVisitor {
return aw;
}
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(final int typeRef,
+ final TypePath typePath, final String desc, final boolean visible) {
+ if (!ClassReader.ANNOTATIONS) {
+ return null;
+ }
+ ByteVector bv = new ByteVector();
+ // write target_type and target_info
+ AnnotationWriter.putTarget(typeRef, typePath, bv);
+ // write type, and reserve space for values count
+ bv.putShort(cw.newUTF8(desc)).putShort(0);
+ AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+ bv.length - 2);
+ if (visible) {
+ aw.next = tanns;
+ tanns = aw;
+ } else {
+ aw.next = itanns;
+ itanns = aw;
+ }
+ return aw;
+ }
+
@Override
public AnnotationVisitor visitParameterAnnotation(final int parameter,
final String desc, final boolean visible) {
@@ -642,6 +712,7 @@ class MethodWriter extends MethodVisitor {
@Override
public void visitInsn(final int opcode) {
+ lastCodeOffset = code.length;
// adds the instruction to the bytecode of the method
code.putByte(opcode);
// update currentBlock
@@ -667,6 +738,7 @@ class MethodWriter extends MethodVisitor {
@Override
public void visitIntInsn(final int opcode, final int operand) {
+ lastCodeOffset = code.length;
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
if (compute == FRAMES) {
@@ -691,6 +763,7 @@ class MethodWriter extends MethodVisitor {
@Override
public void visitVarInsn(final int opcode, final int var) {
+ lastCodeOffset = code.length;
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
if (compute == FRAMES) {
@@ -749,6 +822,7 @@ class MethodWriter extends MethodVisitor {
@Override
public void visitTypeInsn(final int opcode, final String type) {
+ lastCodeOffset = code.length;
Item i = cw.newClassItem(type);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
@@ -771,6 +845,7 @@ class MethodWriter extends MethodVisitor {
@Override
public void visitFieldInsn(final int opcode, final String owner,
final String name, final String desc) {
+ lastCodeOffset = code.length;
Item i = cw.newFieldItem(owner, name, desc);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
@@ -809,6 +884,7 @@ class MethodWriter extends MethodVisitor {
@Override
public void visitMethodInsn(final int opcode, final String owner,
final String name, final String desc) {
+ lastCodeOffset = code.length;
boolean itf = opcode == Opcodes.INVOKEINTERFACE;
Item i = cw.newMethodItem(owner, name, desc, itf);
int argSize = i.intVal;
@@ -861,6 +937,7 @@ class MethodWriter extends MethodVisitor {
@Override
public void visitInvokeDynamicInsn(final String name, final String desc,
final Handle bsm, final Object... bsmArgs) {
+ lastCodeOffset = code.length;
Item i = cw.newInvokeDynamicItem(name, desc, bsm, bsmArgs);
int argSize = i.intVal;
// Label currentBlock = this.currentBlock;
@@ -900,6 +977,7 @@ class MethodWriter extends MethodVisitor {
@Override
public void visitJumpInsn(final int opcode, final Label label) {
+ lastCodeOffset = code.length;
Label nextInsn = null;
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
@@ -1045,6 +1123,7 @@ class MethodWriter extends MethodVisitor {
@Override
public void visitLdcInsn(final Object cst) {
+ lastCodeOffset = code.length;
Item i = cw.newConstItem(cst);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
@@ -1078,6 +1157,7 @@ class MethodWriter extends MethodVisitor {
@Override
public void visitIincInsn(final int var, final int increment) {
+ lastCodeOffset = code.length;
if (currentBlock != null) {
if (compute == FRAMES) {
currentBlock.frame.execute(Opcodes.IINC, var, null, null);
@@ -1102,6 +1182,7 @@ class MethodWriter extends MethodVisitor {
@Override
public void visitTableSwitchInsn(final int min, final int max,
final Label dflt, final Label... labels) {
+ lastCodeOffset = code.length;
// adds the instruction to the bytecode of the method
int source = code.length;
code.putByte(Opcodes.TABLESWITCH);
@@ -1118,6 +1199,7 @@ class MethodWriter extends MethodVisitor {
@Override
public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
final Label[] labels) {
+ lastCodeOffset = code.length;
// adds the instruction to the bytecode of the method
int source = code.length;
code.putByte(Opcodes.LOOKUPSWITCH);
@@ -1160,6 +1242,7 @@ class MethodWriter extends MethodVisitor {
@Override
public void visitMultiANewArrayInsn(final String desc, final int dims) {
+ lastCodeOffset = code.length;
Item i = cw.newClassItem(desc);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
@@ -1175,6 +1258,30 @@ class MethodWriter extends MethodVisitor {
code.put12(Opcodes.MULTIANEWARRAY, i.index).putByte(dims);
}
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ if (!ClassReader.ANNOTATIONS) {
+ return null;
+ }
+ ByteVector bv = new ByteVector();
+ // write target_type and target_info
+ typeRef = (typeRef & 0xFF0000FF) | (lastCodeOffset << 8);
+ AnnotationWriter.putTarget(typeRef, typePath, bv);
+ // write type, and reserve space for values count
+ bv.putShort(cw.newUTF8(desc)).putShort(0);
+ AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+ bv.length - 2);
+ if (visible) {
+ aw.next = ctanns;
+ ctanns = aw;
+ } else {
+ aw.next = ictanns;
+ ictanns = aw;
+ }
+ return aw;
+ }
+
@Override
public void visitTryCatchBlock(final Label start, final Label end,
final Label handler, final String type) {
@@ -1193,6 +1300,29 @@ class MethodWriter extends MethodVisitor {
lastHandler = h;
}
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ if (!ClassReader.ANNOTATIONS) {
+ return null;
+ }
+ ByteVector bv = new ByteVector();
+ // write target_type and target_info
+ AnnotationWriter.putTarget(typeRef, typePath, bv);
+ // write type, and reserve space for values count
+ bv.putShort(cw.newUTF8(desc)).putShort(0);
+ AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+ bv.length - 2);
+ if (visible) {
+ aw.next = ctanns;
+ ctanns = aw;
+ } else {
+ aw.next = ictanns;
+ ictanns = aw;
+ }
+ return aw;
+ }
+
@Override
public void visitLocalVariable(final String name, final String desc,
final String signature, final Label start, final Label end,
@@ -1225,6 +1355,41 @@ class MethodWriter extends MethodVisitor {
}
}
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+ TypePath typePath, Label[] start, Label[] end, int[] index,
+ String desc, boolean visible) {
+ if (!ClassReader.ANNOTATIONS) {
+ return null;
+ }
+ ByteVector bv = new ByteVector();
+ // write target_type and target_info
+ bv.putByte(typeRef >>> 24).putShort(start.length);
+ for (int i = 0; i < start.length; ++i) {
+ bv.putShort(start[i].position)
+ .putShort(end[i].position - start[i].position)
+ .putShort(index[i]);
+ }
+ if (typePath == null) {
+ bv.putByte(0);
+ } else {
+ int length = typePath.b[typePath.offset] * 2 + 1;
+ bv.putByteArray(typePath.b, typePath.offset, length);
+ }
+ // write type, and reserve space for values count
+ bv.putShort(cw.newUTF8(desc)).putShort(0);
+ AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+ bv.length - 2);
+ if (visible) {
+ aw.next = ctanns;
+ ctanns = aw;
+ } else {
+ aw.next = ictanns;
+ ictanns = aw;
+ }
+ return aw;
+ }
+
@Override
public void visitLineNumber(final int line, final Label start) {
if (lineNumber == null) {
@@ -1768,7 +1933,7 @@ class MethodWriter extends MethodVisitor {
/**
* Writes some types of the current frame {@link #frame} into the
* StackMapTableAttribute. This method converts types from the format used
- * in {@link org.objectweb.asm.Label} to the format used in StackMapTable attributes. In
+ * in {@link Label} to the format used in StackMapTable attributes. In
* particular, it converts type table indexes to constant pool indexes.
*
* @param start
@@ -1890,6 +2055,14 @@ class MethodWriter extends MethodVisitor {
cw.newUTF8(zip ? "StackMapTable" : "StackMap");
size += 8 + stackMap.length;
}
+ if (ClassReader.ANNOTATIONS && ctanns != null) {
+ cw.newUTF8("RuntimeVisibleTypeAnnotations");
+ size += 8 + ctanns.getSize();
+ }
+ if (ClassReader.ANNOTATIONS && ictanns != null) {
+ cw.newUTF8("RuntimeInvisibleTypeAnnotations");
+ size += 8 + ictanns.getSize();
+ }
if (cattrs != null) {
size += cattrs.getSize(cw, code.data, code.length, maxStack,
maxLocals);
@@ -1915,6 +2088,10 @@ class MethodWriter extends MethodVisitor {
cw.newUTF8(signature);
size += 8;
}
+ if (methodParameters != null) {
+ cw.newUTF8("MethodParameters");
+ size += 7 + methodParameters.length;
+ }
if (ClassReader.ANNOTATIONS && annd != null) {
cw.newUTF8("AnnotationDefault");
size += 6 + annd.length;
@@ -1927,6 +2104,14 @@ class MethodWriter extends MethodVisitor {
cw.newUTF8("RuntimeInvisibleAnnotations");
size += 8 + ianns.getSize();
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ cw.newUTF8("RuntimeVisibleTypeAnnotations");
+ size += 8 + tanns.getSize();
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ cw.newUTF8("RuntimeInvisibleTypeAnnotations");
+ size += 8 + itanns.getSize();
+ }
if (ClassReader.ANNOTATIONS && panns != null) {
cw.newUTF8("RuntimeVisibleParameterAnnotations");
size += 7 + 2 * (panns.length - synthetics);
@@ -1983,6 +2168,9 @@ class MethodWriter extends MethodVisitor {
if (ClassReader.SIGNATURES && signature != null) {
++attributeCount;
}
+ if (methodParameters != null) {
+ ++attributeCount;
+ }
if (ClassReader.ANNOTATIONS && annd != null) {
++attributeCount;
}
@@ -1992,6 +2180,12 @@ class MethodWriter extends MethodVisitor {
if (ClassReader.ANNOTATIONS && ianns != null) {
++attributeCount;
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ ++attributeCount;
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ ++attributeCount;
+ }
if (ClassReader.ANNOTATIONS && panns != null) {
++attributeCount;
}
@@ -2016,6 +2210,12 @@ class MethodWriter extends MethodVisitor {
if (stackMap != null) {
size += 8 + stackMap.length;
}
+ if (ClassReader.ANNOTATIONS && ctanns != null) {
+ size += 8 + ctanns.getSize();
+ }
+ if (ClassReader.ANNOTATIONS && ictanns != null) {
+ size += 8 + ictanns.getSize();
+ }
if (cattrs != null) {
size += cattrs.getSize(cw, code.data, code.length, maxStack,
maxLocals);
@@ -2045,6 +2245,12 @@ class MethodWriter extends MethodVisitor {
if (stackMap != null) {
++attributeCount;
}
+ if (ClassReader.ANNOTATIONS && ctanns != null) {
+ ++attributeCount;
+ }
+ if (ClassReader.ANNOTATIONS && ictanns != null) {
+ ++attributeCount;
+ }
if (cattrs != null) {
attributeCount += cattrs.getCount();
}
@@ -2070,6 +2276,14 @@ class MethodWriter extends MethodVisitor {
out.putInt(stackMap.length + 2).putShort(frameCount);
out.putByteArray(stackMap.data, 0, stackMap.length);
}
+ if (ClassReader.ANNOTATIONS && ctanns != null) {
+ out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
+ ctanns.put(out);
+ }
+ if (ClassReader.ANNOTATIONS && ictanns != null) {
+ out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
+ ictanns.put(out);
+ }
if (cattrs != null) {
cattrs.put(cw, code.data, code.length, maxLocals, maxStack, out);
}
@@ -2095,6 +2309,12 @@ class MethodWriter extends MethodVisitor {
out.putShort(cw.newUTF8("Signature")).putInt(2)
.putShort(cw.newUTF8(signature));
}
+ if (methodParameters != null) {
+ out.putShort(cw.newUTF8("MethodParameters"));
+ out.putInt(methodParameters.length + 1).putByte(
+ methodParametersCount);
+ out.putByteArray(methodParameters.data, 0, methodParameters.length);
+ }
if (ClassReader.ANNOTATIONS && annd != null) {
out.putShort(cw.newUTF8("AnnotationDefault"));
out.putInt(annd.length);
@@ -2108,6 +2328,14 @@ class MethodWriter extends MethodVisitor {
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out);
}
+ if (ClassReader.ANNOTATIONS && tanns != null) {
+ out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
+ tanns.put(out);
+ }
+ if (ClassReader.ANNOTATIONS && itanns != null) {
+ out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
+ itanns.put(out);
+ }
if (ClassReader.ANNOTATIONS && panns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations"));
AnnotationWriter.put(panns, synthetics, out);
@@ -2127,7 +2355,7 @@ class MethodWriter extends MethodVisitor {
/**
* Resizes and replaces the temporary instructions inserted by
- * {@link org.objectweb.asm.Label#resolve} for wide forward jumps, while keeping jump offsets
+ * {@link Label#resolve} for wide forward jumps, while keeping jump offsets
* and instruction addresses consistent. This may require to resize other
* existing instructions, or even to introduce new instructions: for
* example, increasing the size of an instruction by 2 at the middle of a
@@ -2138,7 +2366,7 @@ class MethodWriter extends MethodVisitor {
* by this method.
*
* This method must be called after all the method that is being built - * has been visited. In particular, the {@link org.objectweb.asm.Label Label} objects used + * has been visited. In particular, the {@link Label Label} objects used * to construct the method are no longer valid after this method has been * called. */ diff --git a/parabotv2/src/org/objectweb/asm/Opcodes.java b/parabotv2/src/org/objectweb/asm/Opcodes.java index 0796eb8..e5c2b33 100644 --- a/parabotv2/src/org/objectweb/asm/Opcodes.java +++ b/parabotv2/src/org/objectweb/asm/Opcodes.java @@ -46,6 +46,7 @@ public interface Opcodes { // ASM API versions int ASM4 = 4 << 16 | 0 << 8 | 0; + int ASM5 = 5 << 16 | 0 << 8 | 0; // versions @@ -56,6 +57,7 @@ public interface Opcodes { int V1_5 = 0 << 16 | 49; int V1_6 = 0 << 16 | 50; int V1_7 = 0 << 16 | 51; + int V1_8 = 0 << 16 | 52; // access flags @@ -63,7 +65,7 @@ public interface Opcodes { int ACC_PRIVATE = 0x0002; // class, field, method int ACC_PROTECTED = 0x0004; // class, field, method int ACC_STATIC = 0x0008; // field, method - int ACC_FINAL = 0x0010; // class, field, method + int ACC_FINAL = 0x0010; // class, field, method, parameter int ACC_SUPER = 0x0020; // class int ACC_SYNCHRONIZED = 0x0020; // method int ACC_VOLATILE = 0x0040; // field @@ -74,9 +76,10 @@ public interface Opcodes { int ACC_INTERFACE = 0x0200; // class int ACC_ABSTRACT = 0x0400; // class, method int ACC_STRICT = 0x0800; // method - int ACC_SYNTHETIC = 0x1000; // class, field, method + int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter int ACC_ANNOTATION = 0x2000; // class int ACC_ENUM = 0x4000; // class(?) field inner + int ACC_MANDATED = 0x8000; // parameter // ASM specific pseudo access flags @@ -108,7 +111,7 @@ public interface Opcodes { // stack map frame types /** - * Represents an expanded frame. See {@link org.objectweb.asm.ClassReader#EXPAND_FRAMES}. + * Represents an expanded frame. See {@link ClassReader#EXPAND_FRAMES}. */ int F_NEW = -1; diff --git a/parabotv2/src/org/objectweb/asm/Type.java b/parabotv2/src/org/objectweb/asm/Type.java index b44d0c7..2ce4cb3 100644 --- a/parabotv2/src/org/objectweb/asm/Type.java +++ b/parabotv2/src/org/objectweb/asm/Type.java @@ -294,7 +294,7 @@ public class Type { * Returns the Java method type corresponding to the given constructor. * * @param c - * a {@link java.lang.reflect.Constructor Constructor} object. + * a {@link Constructor Constructor} object. * @return the Java method type corresponding to the given constructor. */ public static Type getType(final Constructor> c) { @@ -305,7 +305,7 @@ public class Type { * Returns the Java method type corresponding to the given method. * * @param m - * a {@link java.lang.reflect.Method Method} object. + * a {@link Method Method} object. * @return the Java method type corresponding to the given method. */ public static Type getType(final Method m) { @@ -401,8 +401,8 @@ public class Type { * @return the size of the arguments of the method (plus one for the * implicit this argument), argSize, and the size of its return * value, retSize, packed into a single int i = - * (argSize << 2) | retSize (argSize is therefore equal to - * i >> 2, and retSize to i & 0x03). + * (argSize << 2) | retSize (argSize is therefore equal to + * i >> 2, and retSize to i & 0x03). */ public static int getArgumentsAndReturnSizes(final String desc) { int n = 1; @@ -606,9 +606,10 @@ public class Type { * * @return the size of the arguments (plus one for the implicit this * argument), argSize, and the size of the return value, retSize, - * packed into a single int i = (argSize << 2) | retSize - * (argSize is therefore equal to i >> 2, and retSize to - * i & 0x03). + * packed into a single + * int i = (argSize << 2) | retSize + * (argSize is therefore equal to i >> 2, + * and retSize to i & 0x03). */ public int getArgumentsAndReturnSizes() { return getArgumentsAndReturnSizes(getDescriptor()); @@ -708,7 +709,7 @@ public class Type { * Returns the descriptor corresponding to the given constructor. * * @param c - * a {@link java.lang.reflect.Constructor Constructor} object. + * a {@link Constructor Constructor} object. * @return the descriptor of the given constructor. */ public static String getConstructorDescriptor(final Constructor> c) { @@ -725,7 +726,7 @@ public class Type { * Returns the descriptor corresponding to the given method. * * @param m - * a {@link java.lang.reflect.Method Method} object. + * a {@link Method Method} object. * @return the descriptor of the given method. */ public static String getMethodDescriptor(final Method m) { diff --git a/parabotv2/src/org/objectweb/asm/TypePath.java b/parabotv2/src/org/objectweb/asm/TypePath.java new file mode 100644 index 0000000..3c5f984 --- /dev/null +++ b/parabotv2/src/org/objectweb/asm/TypePath.java @@ -0,0 +1,193 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2013 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.objectweb.asm; + +/** + * The path to a type argument, wildcard bound, array element type, or static + * inner type within an enclosing type. + * + * @author Eric Bruneton + */ +public class TypePath { + + /** + * A type path step that steps into the element type of an array type. See + * {@link #getStep getStep}. + */ + public final static int ARRAY_ELEMENT = 0; + + /** + * A type path step that steps into the nested type of a class type. See + * {@link #getStep getStep}. + */ + public final static int INNER_TYPE = 1; + + /** + * A type path step that steps into the bound of a wildcard type. See + * {@link #getStep getStep}. + */ + public final static int WILDCARD_BOUND = 2; + + /** + * A type path step that steps into a type argument of a generic type. See + * {@link #getStep getStep}. + */ + public final static int TYPE_ARGUMENT = 3; + + /** + * The byte array where the path is stored, in Java class file format. + */ + byte[] b; + + /** + * The offset of the first byte of the type path in 'b'. + */ + int offset; + + /** + * Creates a new type path. + * + * @param b + * the byte array containing the type path in Java class file + * format. + * @param offset + * the offset of the first byte of the type path in 'b'. + */ + TypePath(byte[] b, int offset) { + this.b = b; + this.offset = offset; + } + + /** + * Returns the length of this path. + * + * @return the length of this path. + */ + public int getLength() { + return b[offset]; + } + + /** + * Returns the value of the given step of this path. + * + * @param index + * an index between 0 and {@link #getLength()}, exclusive. + * @return {@link #ARRAY_ELEMENT ARRAY_ELEMENT}, {@link #INNER_TYPE + * INNER_TYPE}, {@link #WILDCARD_BOUND WILDCARD_BOUND}, or + * {@link #TYPE_ARGUMENT TYPE_ARGUMENT}. + */ + public int getStep(int index) { + return b[offset + 2 * index + 1]; + } + + /** + * Returns the index of the type argument that the given step is stepping + * into. This method should only be used for steps whose value is + * {@link #TYPE_ARGUMENT TYPE_ARGUMENT}. + * + * @param index + * an index between 0 and {@link #getLength()}, exclusive. + * @return the index of the type argument that the given step is stepping + * into. + */ + public int getStepArgument(int index) { + return b[offset + 2 * index + 2]; + } + + /** + * Converts a type path in string form, in the format used by + * {@link #toString()}, into a TypePath object. + * + * @param typePath + * a type path in string form, in the format used by + * {@link #toString()}. May be null or empty. + * @return the corresponding TypePath object, or null if the path is empty. + */ + public static TypePath fromString(final String typePath) { + if (typePath == null || typePath.length() == 0) { + return null; + } + int n = typePath.length(); + ByteVector out = new ByteVector(n); + out.putByte(0); + for (int i = 0; i < n;) { + char c = typePath.charAt(i++); + if (c == '[') { + out.put11(ARRAY_ELEMENT, 0); + } else if (c == '.') { + out.put11(INNER_TYPE, 0); + } else if (c == '*') { + out.put11(WILDCARD_BOUND, 0); + } else if (c >= '0' && c <= '9') { + int typeArg = c - '0'; + while (i < n && (c = typePath.charAt(i)) >= '0' && c <= '9') { + typeArg = typeArg * 10 + c - '0'; + i += 1; + } + out.put11(TYPE_ARGUMENT, typeArg); + } + } + out.data[0] = (byte) (out.length / 2); + return new TypePath(out.data, 0); + } + + /** + * Returns a string representation of this type path. {@link #ARRAY_ELEMENT + * ARRAY_ELEMENT} steps are represented with '[', {@link #INNER_TYPE + * INNER_TYPE} steps with '.', {@link #WILDCARD_BOUND WILDCARD_BOUND} steps + * with '*' and {@link #TYPE_ARGUMENT TYPE_ARGUMENT} steps with their type + * argument index in decimal form. + */ + @Override + public String toString() { + int length = getLength(); + StringBuilder result = new StringBuilder(length * 2); + for (int i = 0; i < length; ++i) { + switch (getStep(i)) { + case ARRAY_ELEMENT: + result.append('['); + break; + case INNER_TYPE: + result.append('.'); + break; + case WILDCARD_BOUND: + result.append('*'); + break; + case TYPE_ARGUMENT: + result.append(getStepArgument(i)); + break; + default: + result.append('_'); + } + } + return result.toString(); + } +} diff --git a/parabotv2/src/org/objectweb/asm/TypeReference.java b/parabotv2/src/org/objectweb/asm/TypeReference.java new file mode 100644 index 0000000..dff76c0 --- /dev/null +++ b/parabotv2/src/org/objectweb/asm/TypeReference.java @@ -0,0 +1,452 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2013 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.objectweb.asm; + +/** + * A reference to a type appearing in a class, field or method declaration, or + * on an instruction. Such a reference designates the part of the class where + * the referenced type is appearing (e.g. an 'extends', 'implements' or 'throws' + * clause, a 'new' instruction, a 'catch' clause, a type cast, a local variable + * declaration, etc). + * + * @author Eric Bruneton + */ +public class TypeReference { + + /** + * The sort of type references that target a type parameter of a generic + * class. See {@link #getSort getSort}. + */ + public final static int CLASS_TYPE_PARAMETER = 0x00; + + /** + * The sort of type references that target a type parameter of a generic + * method. See {@link #getSort getSort}. + */ + public final static int METHOD_TYPE_PARAMETER = 0x01; + + /** + * The sort of type references that target the super class of a class or one + * of the interfaces it implements. See {@link #getSort getSort}. + */ + public final static int CLASS_EXTENDS = 0x10; + + /** + * The sort of type references that target a bound of a type parameter of a + * generic class. See {@link #getSort getSort}. + */ + public final static int CLASS_TYPE_PARAMETER_BOUND = 0x11; + + /** + * The sort of type references that target a bound of a type parameter of a + * generic method. See {@link #getSort getSort}. + */ + public final static int METHOD_TYPE_PARAMETER_BOUND = 0x12; + + /** + * The sort of type references that target the type of a field. See + * {@link #getSort getSort}. + */ + public final static int FIELD = 0x13; + + /** + * The sort of type references that target the return type of a method. See + * {@link #getSort getSort}. + */ + public final static int METHOD_RETURN = 0x14; + + /** + * The sort of type references that target the receiver type of a method. + * See {@link #getSort getSort}. + */ + public final static int METHOD_RECEIVER = 0x15; + + /** + * The sort of type references that target the type of a formal parameter of + * a method. See {@link #getSort getSort}. + */ + public final static int METHOD_FORMAL_PARAMETER = 0x16; + + /** + * The sort of type references that target the type of an exception declared + * in the throws clause of a method. See {@link #getSort getSort}. + */ + public final static int THROWS = 0x17; + + /** + * The sort of type references that target the type of a local variable in a + * method. See {@link #getSort getSort}. + */ + public final static int LOCAL_VARIABLE = 0x40; + + /** + * The sort of type references that target the type of a resource variable + * in a method. See {@link #getSort getSort}. + */ + public final static int RESOURCE_VARIABLE = 0x41; + + /** + * The sort of type references that target the type of the exception of a + * 'catch' clause in a method. See {@link #getSort getSort}. + */ + public final static int EXCEPTION_PARAMETER = 0x42; + + /** + * The sort of type references that target the type declared in an + * 'instanceof' instruction. See {@link #getSort getSort}. + */ + public final static int INSTANCEOF = 0x43; + + /** + * The sort of type references that target the type of the object created by + * a 'new' instruction. See {@link #getSort getSort}. + */ + public final static int NEW = 0x44; + + /** + * The sort of type references that target the receiver type of a + * constructor reference. See {@link #getSort getSort}. + */ + public final static int CONSTRUCTOR_REFERENCE = 0x45; + + /** + * The sort of type references that target the receiver type of a method + * reference. See {@link #getSort getSort}. + */ + public final static int METHOD_REFERENCE = 0x46; + + /** + * The sort of type references that target the type declared in an explicit + * or implicit cast instruction. See {@link #getSort getSort}. + */ + public final static int CAST = 0x47; + + /** + * The sort of type references that target a type parameter of a generic + * constructor in a constructor call. See {@link #getSort getSort}. + */ + public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48; + + /** + * The sort of type references that target a type parameter of a generic + * method in a method call. See {@link #getSort getSort}. + */ + public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49; + + /** + * The sort of type references that target a type parameter of a generic + * constructor in a constructor reference. See {@link #getSort getSort}. + */ + public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A; + + /** + * The sort of type references that target a type parameter of a generic + * method in a method reference. See {@link #getSort getSort}. + */ + public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B; + + /** + * The type reference value in Java class file format. + */ + private int value; + + /** + * Creates a new TypeReference. + * + * @param typeRef + * the int encoded value of the type reference, as received in a + * visit method related to type annotations, like + * visitTypeAnnotation. + */ + public TypeReference(int typeRef) { + this.value = typeRef; + } + + /** + * Returns a type reference of the given sort. + * + * @param sort + * {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN}, + * {@link #METHOD_RECEIVER METHOD_RECEIVER}, + * {@link #LOCAL_VARIABLE LOCAL_VARIABLE}, + * {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE}, + * {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW}, + * {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, or + * {@link #METHOD_REFERENCE METHOD_REFERENCE}. + * @return a type reference of the given sort. + */ + public static TypeReference newTypeReference(int sort) { + return new TypeReference(sort << 24); + } + + /** + * Returns a reference to a type parameter of a generic class or method. + * + * @param sort + * {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or + * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}. + * @param paramIndex + * the type parameter index. + * @return a reference to the given generic class or method type parameter. + */ + public static TypeReference newTypeParameterReference(int sort, + int paramIndex) { + return new TypeReference((sort << 24) | (paramIndex << 16)); + } + + /** + * Returns a reference to a type parameter bound of a generic class or + * method. + * + * @param sort + * {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or + * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}. + * @param paramIndex + * the type parameter index. + * @param boundIndex + * the type bound index within the above type parameters. + * @return a reference to the given generic class or method type parameter + * bound. + */ + public static TypeReference newTypeParameterBoundReference(int sort, + int paramIndex, int boundIndex) { + return new TypeReference((sort << 24) | (paramIndex << 16) + | (boundIndex << 8)); + } + + /** + * Returns a reference to the super class or to an interface of the + * 'implements' clause of a class. + * + * @param itfIndex + * the index of an interface in the 'implements' clause of a + * class, or -1 to reference the super class of the class. + * @return a reference to the given super type of a class. + */ + public static TypeReference newSuperTypeReference(int itfIndex) { + itfIndex &= 0xFFFF; + return new TypeReference((CLASS_EXTENDS << 24) | (itfIndex << 8)); + } + + /** + * Returns a reference to the type of a formal parameter of a method. + * + * @param paramIndex + * the formal parameter index. + * + * @return a reference to the type of the given method formal parameter. + */ + public static TypeReference newFormalParameterReference(int paramIndex) { + return new TypeReference((METHOD_FORMAL_PARAMETER << 24) + | (paramIndex << 16)); + } + + /** + * Returns a reference to the type of an exception, in a 'throws' clause of + * a method. + * + * @param exceptionIndex + * the index of an exception in a 'throws' clause of a method. + * + * @return a reference to the type of the given exception. + */ + public static TypeReference newExceptionReference(int exceptionIndex) { + return new TypeReference((THROWS << 24) | (exceptionIndex << 8)); + } + + /** + * Returns a reference to the type of the exception declared in a 'catch' + * clause of a method. + * + * @param tryCatchBlockIndex + * the index of a try catch block (using the order in which they + * are visited with visitTryCatchBlock). + * + * @return a reference to the type of the given exception. + */ + public static TypeReference newTryCatchReference(int tryCatchBlockIndex) { + return new TypeReference((EXCEPTION_PARAMETER << 24) + | (tryCatchBlockIndex << 8)); + } + + /** + * Returns a reference to the type of a type argument in a constructor or + * method call or reference. + * + * @param sort + * {@link #CAST CAST}, + * {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT + * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, + * {@link #METHOD_INVOCATION_TYPE_ARGUMENT + * METHOD_INVOCATION_TYPE_ARGUMENT}, + * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT + * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or + * {@link #METHOD_REFERENCE_TYPE_ARGUMENT + * METHOD_REFERENCE_TYPE_ARGUMENT}. + * @param argIndex + * the type argument index. + * + * @return a reference to the type of the given type argument. + */ + public static TypeReference newTypeArgumentReference(int sort, int argIndex) { + return new TypeReference((sort << 24) | argIndex); + } + + /** + * Returns the sort of this type reference. + * + * @return {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER}, + * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}, + * {@link #CLASS_EXTENDS CLASS_EXTENDS}, + * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND}, + * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}, + * {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN}, + * {@link #METHOD_RECEIVER METHOD_RECEIVER}, + * {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}, + * {@link #THROWS THROWS}, {@link #LOCAL_VARIABLE LOCAL_VARIABLE}, + * {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE}, + * {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER}, + * {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW}, + * {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, + * {@link #METHOD_REFERENCE METHOD_REFERENCE}, {@link #CAST CAST}, + * {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT + * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, + * {@link #METHOD_INVOCATION_TYPE_ARGUMENT + * METHOD_INVOCATION_TYPE_ARGUMENT}, + * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT + * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or + * {@link #METHOD_REFERENCE_TYPE_ARGUMENT + * METHOD_REFERENCE_TYPE_ARGUMENT}. + */ + public int getSort() { + return value >>> 24; + } + + /** + * Returns the index of the type parameter referenced by this type + * reference. This method must only be used for type references whose sort + * is {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER}, + * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}, + * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or + * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}. + * + * @return a type parameter index. + */ + public int getTypeParameterIndex() { + return (value & 0x00FF0000) >> 16; + } + + /** + * Returns the index of the type parameter bound, within the type parameter + * {@link #getTypeParameterIndex}, referenced by this type reference. This + * method must only be used for type references whose sort is + * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or + * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}. + * + * @return a type parameter bound index. + */ + public int getTypeParameterBoundIndex() { + return (value & 0x0000FF00) >> 8; + } + + /** + * Returns the index of the "super type" of a class that is referenced by + * this type reference. This method must only be used for type references + * whose sort is {@link #CLASS_EXTENDS CLASS_EXTENDS}. + * + * @return the index of an interface in the 'implements' clause of a class, + * or -1 if this type reference references the type of the super + * class. + */ + public int getSuperTypeIndex() { + return (short) ((value & 0x00FFFF00) >> 8); + } + + /** + * Returns the index of the formal parameter whose type is referenced by + * this type reference. This method must only be used for type references + * whose sort is {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}. + * + * @return a formal parameter index. + */ + public int getFormalParameterIndex() { + return (value & 0x00FF0000) >> 16; + } + + /** + * Returns the index of the exception, in a 'throws' clause of a method, + * whose type is referenced by this type reference. This method must only be + * used for type references whose sort is {@link #THROWS THROWS}. + * + * @return the index of an exception in the 'throws' clause of a method. + */ + public int getExceptionIndex() { + return (value & 0x00FFFF00) >> 8; + } + + /** + * Returns the index of the try catch block (using the order in which they + * are visited with visitTryCatchBlock), whose 'catch' type is referenced by + * this type reference. This method must only be used for type references + * whose sort is {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER} . + * + * @return the index of an exception in the 'throws' clause of a method. + */ + public int getTryCatchBlockIndex() { + return (value & 0x00FFFF00) >> 8; + } + + /** + * Returns the index of the type argument referenced by this type reference. + * This method must only be used for type references whose sort is + * {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT + * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, + * {@link #METHOD_INVOCATION_TYPE_ARGUMENT METHOD_INVOCATION_TYPE_ARGUMENT}, + * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT + * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or + * {@link #METHOD_REFERENCE_TYPE_ARGUMENT METHOD_REFERENCE_TYPE_ARGUMENT}. + * + * @return a type parameter index. + */ + public int getTypeArgumentIndex() { + return value & 0xFF; + } + + /** + * Returns the int encoded value of this type reference, suitable for use in + * visit methods related to type annotations, like visitTypeAnnotation. + * + * @return the int encoded value of this type reference. + */ + public int getValue() { + return value; + } +} diff --git a/parabotv2/src/org/objectweb/asm/package.html b/parabotv2/src/org/objectweb/asm/package.html deleted file mode 100644 index 2d4a765..0000000 --- a/parabotv2/src/org/objectweb/asm/package.html +++ /dev/null @@ -1,87 +0,0 @@ - - -
-Provides a small and fast bytecode manipulation framework. - --The ASM framework is organized -around the {@link org.objectweb.asm.ClassVisitor ClassVisitor}, -{@link org.objectweb.asm.FieldVisitor FieldVisitor}, -{@link org.objectweb.asm.MethodVisitor MethodVisitor} and -{@link org.objectweb.asm.AnnotationVisitor AnnotationVisitor} abstract classes, -which allow one to visit the fields, methods and annotations of a class, -including the bytecode instructions of each method. - -
-In addition to these main abstract classes, ASM provides a {@link -org.objectweb.asm.ClassReader ClassReader} class, that can parse an -existing class and make a given visitor visit it. ASM also provides -a {@link org.objectweb.asm.ClassWriter ClassWriter} class, which is -a visitor that generates Java class files. - -
-In order to generate a class from scratch, only the {@link -org.objectweb.asm.ClassWriter ClassWriter} class is necessary. Indeed, -in order to generate a class, one must just call its visitXxx -methods with the appropriate arguments to generate the desired fields -and methods. See the "helloworld" example in the ASM distribution for -more details about class generation. - -
-In order to modify existing classes, one must use a {@link -org.objectweb.asm.ClassReader ClassReader} class to analyze -the original class, a class modifier, and a {@link org.objectweb.asm.ClassWriter -ClassWriter} to construct the modified class. The class modifier -is just a {@link org.objectweb.asm.ClassVisitor ClassVisitor} -that delegates most of the work to another {@link org.objectweb.asm.ClassVisitor -ClassVisitor}, but that sometimes changes some parameter values, -or call additional methods, in order to implement the desired -modification process. In order to make it easier to implement such -class modifiers, the {@link org.objectweb.asm.ClassVisitor -ClassVisitor} and {@link org.objectweb.asm.MethodVisitor MethodVisitor} -classes delegate by default all the method calls they receive to an -optional visitor. See the "adapt" example in the ASM -distribution for more details about class modification. - -
-The size of the core ASM library, asm.jar, is only 45KB, which is much
-smaller than the size of the
-BCEL library (504KB), and than the
-size of the
-SERP library (150KB). ASM is also
-much faster than these tools. Indeed the overhead of a load time class
-transformation process is of the order of 60% with ASM, 700% or more with BCEL,
-and 1100% or more with SERP (see the test/perf directory in the ASM
-distribution)!
-
-@since ASM 1.3
-
-
diff --git a/parabotv2/src/org/objectweb/asm/signature/SignatureReader.java b/parabotv2/src/org/objectweb/asm/signature/SignatureReader.java
index b559612..1083b3d 100644
--- a/parabotv2/src/org/objectweb/asm/signature/SignatureReader.java
+++ b/parabotv2/src/org/objectweb/asm/signature/SignatureReader.java
@@ -44,7 +44,7 @@ public class SignatureReader {
private final String signature;
/**
- * Constructs a {@link org.objectweb.asm.signature.SignatureReader} for the given signature.
+ * Constructs a {@link SignatureReader} for the given signature.
*
* @param signature
* A ClassSignature, MethodTypeSignature, or
@@ -56,9 +56,9 @@ public class SignatureReader {
/**
* Makes the given visitor visit the signature of this
- * {@link org.objectweb.asm.signature.SignatureReader}. This signature is the one specified in the
+ * {@link SignatureReader}. This signature is the one specified in the
* constructor (see {@link #SignatureReader(String) SignatureReader}). This
- * method is intended to be called on a {@link org.objectweb.asm.signature.SignatureReader} that was
+ * method is intended to be called on a {@link SignatureReader} that was
* created using a ClassSignature (such as the signature
* parameter of the {@link org.objectweb.asm.ClassVisitor#visit
* ClassVisitor.visit} method) or a MethodTypeSignature (such as the
@@ -114,9 +114,9 @@ public class SignatureReader {
/**
* Makes the given visitor visit the signature of this
- * {@link org.objectweb.asm.signature.SignatureReader}. This signature is the one specified in the
+ * {@link SignatureReader}. This signature is the one specified in the
* constructor (see {@link #SignatureReader(String) SignatureReader}). This
- * method is intended to be called on a {@link org.objectweb.asm.signature.SignatureReader} that was
+ * method is intended to be called on a {@link SignatureReader} that was
* created using a FieldTypeSignature, such as the
* signature parameter of the
* {@link org.objectweb.asm.ClassVisitor#visitField ClassVisitor.visitField}
diff --git a/parabotv2/src/org/objectweb/asm/signature/SignatureVisitor.java b/parabotv2/src/org/objectweb/asm/signature/SignatureVisitor.java
index 47c35bf..053c105 100644
--- a/parabotv2/src/org/objectweb/asm/signature/SignatureVisitor.java
+++ b/parabotv2/src/org/objectweb/asm/signature/SignatureVisitor.java
@@ -29,10 +29,12 @@
*/
package org.objectweb.asm.signature;
+import org.objectweb.asm.Opcodes;
+
/**
* A visitor to visit a generic signature. The methods of this interface must be
* called in one of the three following orders (the last one is the only valid
- * order for a {@link org.objectweb.asm.signature.SignatureVisitor} that is returned by a method of this
+ * order for a {@link SignatureVisitor} that is returned by a method of this
* interface):
*