Updated ASM library (ASM 5)

This commit is contained in:
Clisprail
2014-01-26 00:15:10 +01:00
parent 677b0d4bd1
commit e8729cf8b0
53 changed files with 2740 additions and 413 deletions
+348 -55
View File
@@ -106,7 +106,7 @@ public class ClassReader {
/**
* The class to be parsed. <i>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.</i>
*/
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
* <tt>true</tt> 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. <i>This method is intended for {@link org.objectweb.asm.Attribute} sub classes, and is
* one. <i>This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.</i>
*
* @param item
@@ -1993,7 +2286,7 @@ public class ClassReader {
/**
* Reads a byte value in {@link #b b}. <i>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.</i>
*
* @param index
@@ -2006,7 +2299,7 @@ public class ClassReader {
/**
* Reads an unsigned short value in {@link #b b}. <i>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.</i>
*
* @param index
@@ -2020,7 +2313,7 @@ public class ClassReader {
/**
* Reads a signed short value in {@link #b b}. <i>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.</i>
*
* @param index
@@ -2034,7 +2327,7 @@ public class ClassReader {
/**
* Reads a signed int value in {@link #b b}. <i>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.</i>
*
* @param index
@@ -2049,7 +2342,7 @@ public class ClassReader {
/**
* Reads a signed long value in {@link #b b}. <i>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.</i>
*
* @param index
@@ -2064,7 +2357,7 @@ public class ClassReader {
/**
* Reads an UTF8 string constant pool item in {@link #b b}. <i>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.</i>
*
* @param index
@@ -2139,7 +2432,7 @@ public class ClassReader {
/**
* Reads a class constant pool item in {@link #b b}. <i>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.</i>
*
* @param index
@@ -2159,7 +2452,7 @@ public class ClassReader {
/**
* Reads a numeric or string constant pool item in {@link #b b}. <i>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.</i>
*
* @param item