mirror of
https://github.com/2006-Scape/Parabot.git
synced 2026-07-06 08:39:33 +00:00
Updated ASM library (ASM 5)
This commit is contained in:
@@ -41,7 +41,7 @@ public abstract class AnnotationVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The ASM API version implemented by this visitor. The value of this field
|
* 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;
|
protected final int api;
|
||||||
|
|
||||||
@@ -52,28 +52,28 @@ public abstract class AnnotationVisitor {
|
|||||||
protected AnnotationVisitor av;
|
protected AnnotationVisitor av;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.AnnotationVisitor}.
|
* Constructs a new {@link AnnotationVisitor}.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* the ASM API version implemented by this visitor. Must be one
|
* 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) {
|
public AnnotationVisitor(final int api) {
|
||||||
this(api, null);
|
this(api, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.AnnotationVisitor}.
|
* Constructs a new {@link AnnotationVisitor}.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* the ASM API version implemented by this visitor. Must be one
|
* 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
|
* @param av
|
||||||
* the annotation visitor to which this visitor must delegate
|
* the annotation visitor to which this visitor must delegate
|
||||||
* method calls. May be null.
|
* method calls. May be null.
|
||||||
*/
|
*/
|
||||||
public AnnotationVisitor(final int api, final AnnotationVisitor av) {
|
public AnnotationVisitor(final int api, final AnnotationVisitor av) {
|
||||||
if (api != Opcodes.ASM4) {
|
if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
this.api = api;
|
this.api = api;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
package org.objectweb.asm;
|
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 Eric Bruneton
|
||||||
* @author Eugene Kuleshov
|
* @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
|
* @param cw
|
||||||
* the class writer to which this annotation must be added.
|
* 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,
|
AnnotationWriter(final ClassWriter cw, final boolean named,
|
||||||
final ByteVector bv, final ByteVector parent, final int offset) {
|
final ByteVector bv, final ByteVector parent, final int offset) {
|
||||||
super(Opcodes.ASM4);
|
super(Opcodes.ASM5);
|
||||||
this.cw = cw;
|
this.cw = cw;
|
||||||
this.named = named;
|
this.named = named;
|
||||||
this.bv = bv;
|
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
|
||||||
|
* <tt>null</tt> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public class Attribute {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a {@link #type type} attribute. This method must return a
|
* Reads a {@link #type type} attribute. This method must return a
|
||||||
* <i>new</i> {@link org.objectweb.asm.Attribute} object, of type {@link #type type},
|
* <i>new</i> {@link Attribute} object, of type {@link #type type},
|
||||||
* corresponding to the <tt>len</tt> bytes starting at the given offset, in
|
* corresponding to the <tt>len</tt> bytes starting at the given offset, in
|
||||||
* the given class reader.
|
* the given class reader.
|
||||||
*
|
*
|
||||||
@@ -119,7 +119,7 @@ public class Attribute {
|
|||||||
* @param labels
|
* @param labels
|
||||||
* the labels of the method's code, or <tt>null</tt> if the
|
* the labels of the method's code, or <tt>null</tt> if the
|
||||||
* attribute to be read is not a code attribute.
|
* attribute to be read is not a code attribute.
|
||||||
* @return a <i>new</i> {@link org.objectweb.asm.Attribute} object corresponding to the given
|
* @return a <i>new</i> {@link Attribute} object corresponding to the given
|
||||||
* bytes.
|
* bytes.
|
||||||
*/
|
*/
|
||||||
protected Attribute read(final ClassReader cr, final int off,
|
protected Attribute read(final ClassReader cr, final int off,
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class ByteVector {
|
|||||||
int length;
|
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.
|
* size.
|
||||||
*/
|
*/
|
||||||
public ByteVector() {
|
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.
|
* size.
|
||||||
*
|
*
|
||||||
* @param initialSize
|
* @param initialSize
|
||||||
@@ -204,11 +204,14 @@ public class ByteVector {
|
|||||||
* automatically enlarged if necessary.
|
* automatically enlarged if necessary.
|
||||||
*
|
*
|
||||||
* @param s
|
* @param s
|
||||||
* a String.
|
* a String whose UTF8 encoded length must be less than 65536.
|
||||||
* @return this byte vector.
|
* @return this byte vector.
|
||||||
*/
|
*/
|
||||||
public ByteVector putUTF8(final String s) {
|
public ByteVector putUTF8(final String s) {
|
||||||
int charLength = s.length();
|
int charLength = s.length();
|
||||||
|
if (charLength > 65535) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
int len = length;
|
int len = length;
|
||||||
if (len + 2 + charLength > data.length) {
|
if (len + 2 + charLength > data.length) {
|
||||||
enlarge(2 + charLength);
|
enlarge(2 + charLength);
|
||||||
@@ -238,6 +241,9 @@ public class ByteVector {
|
|||||||
byteLength += 2;
|
byteLength += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (byteLength > 65535) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
data[length] = (byte) (byteLength >>> 8);
|
data[length] = (byte) (byteLength >>> 8);
|
||||||
data[length + 1] = (byte) byteLength;
|
data[length + 1] = (byte) byteLength;
|
||||||
if (length + 2 + byteLength > data.length) {
|
if (length + 2 + byteLength > data.length) {
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ public class ClassReader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The class to be parsed. <i>The content of this array must not be
|
* 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>
|
* is normally not needed by class generators or adapters.</i>
|
||||||
*/
|
*/
|
||||||
public final byte[] b;
|
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
|
* @param b
|
||||||
* the bytecode of the class to be read.
|
* 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
|
* @param b
|
||||||
* the bytecode of the class to be read.
|
* 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) {
|
public ClassReader(final byte[] b, final int off, final int len) {
|
||||||
this.b = b;
|
this.b = b;
|
||||||
// checks the class version
|
// checks the class version
|
||||||
if (readShort(off + 6) > Opcodes.V1_7) {
|
if (readShort(off + 6) > Opcodes.V1_8) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
// parses the constant pool
|
// 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
|
* @param is
|
||||||
* an input stream from which to read the class.
|
* an input stream from which to read the class.
|
||||||
* @throws java.io.IOException
|
* @throws IOException
|
||||||
* if a problem occurs during reading.
|
* if a problem occurs during reading.
|
||||||
*/
|
*/
|
||||||
public ClassReader(final InputStream is) throws IOException {
|
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
|
* @param name
|
||||||
* the binary qualified name of the class to be read.
|
* the binary qualified name of the class to be read.
|
||||||
* @throws java.io.IOException
|
* @throws IOException
|
||||||
* if an exception occurs during reading.
|
* if an exception occurs during reading.
|
||||||
*/
|
*/
|
||||||
public ClassReader(final String name) throws IOException {
|
public ClassReader(final String name) throws IOException {
|
||||||
@@ -446,7 +446,7 @@ public class ClassReader {
|
|||||||
* @param close
|
* @param close
|
||||||
* true to close the input stream after reading.
|
* true to close the input stream after reading.
|
||||||
* @return the bytecode read from the given input stream.
|
* @return the bytecode read from the given input stream.
|
||||||
* @throws java.io.IOException
|
* @throws IOException
|
||||||
* if a problem occurs during reading.
|
* if a problem occurs during reading.
|
||||||
*/
|
*/
|
||||||
private static byte[] readClass(final InputStream is, boolean close)
|
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
|
* . This class is the one specified in the constructor (see
|
||||||
* {@link #ClassReader(byte[]) ClassReader}).
|
* {@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
|
* This class is the one specified in the constructor (see
|
||||||
* {@link #ClassReader(byte[]) ClassReader}).
|
* {@link #ClassReader(byte[]) ClassReader}).
|
||||||
*
|
*
|
||||||
@@ -557,6 +557,8 @@ public class ClassReader {
|
|||||||
String enclosingDesc = null;
|
String enclosingDesc = null;
|
||||||
int anns = 0;
|
int anns = 0;
|
||||||
int ianns = 0;
|
int ianns = 0;
|
||||||
|
int tanns = 0;
|
||||||
|
int itanns = 0;
|
||||||
int innerClasses = 0;
|
int innerClasses = 0;
|
||||||
Attribute attributes = null;
|
Attribute attributes = null;
|
||||||
|
|
||||||
@@ -581,6 +583,9 @@ public class ClassReader {
|
|||||||
} else if (ANNOTATIONS
|
} else if (ANNOTATIONS
|
||||||
&& "RuntimeVisibleAnnotations".equals(attrName)) {
|
&& "RuntimeVisibleAnnotations".equals(attrName)) {
|
||||||
anns = u + 8;
|
anns = u + 8;
|
||||||
|
} else if (ANNOTATIONS
|
||||||
|
&& "RuntimeVisibleTypeAnnotations".equals(attrName)) {
|
||||||
|
tanns = u + 8;
|
||||||
} else if ("Deprecated".equals(attrName)) {
|
} else if ("Deprecated".equals(attrName)) {
|
||||||
access |= Opcodes.ACC_DEPRECATED;
|
access |= Opcodes.ACC_DEPRECATED;
|
||||||
} else if ("Synthetic".equals(attrName)) {
|
} else if ("Synthetic".equals(attrName)) {
|
||||||
@@ -592,6 +597,9 @@ public class ClassReader {
|
|||||||
} else if (ANNOTATIONS
|
} else if (ANNOTATIONS
|
||||||
&& "RuntimeInvisibleAnnotations".equals(attrName)) {
|
&& "RuntimeInvisibleAnnotations".equals(attrName)) {
|
||||||
ianns = u + 8;
|
ianns = u + 8;
|
||||||
|
} else if (ANNOTATIONS
|
||||||
|
&& "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
|
||||||
|
itanns = u + 8;
|
||||||
} else if ("BootstrapMethods".equals(attrName)) {
|
} else if ("BootstrapMethods".equals(attrName)) {
|
||||||
int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
|
int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
|
||||||
for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
|
for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
|
||||||
@@ -626,7 +634,7 @@ public class ClassReader {
|
|||||||
enclosingDesc);
|
enclosingDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// visits the class annotations
|
// visits the class annotations and type annotations
|
||||||
if (ANNOTATIONS && anns != 0) {
|
if (ANNOTATIONS && anns != 0) {
|
||||||
for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
|
for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
|
||||||
v = readAnnotationValues(v + 2, c, true,
|
v = readAnnotationValues(v + 2, c, true,
|
||||||
@@ -639,6 +647,22 @@ public class ClassReader {
|
|||||||
classVisitor.visitAnnotation(readUTF8(v, c), false));
|
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
|
// visits the attributes
|
||||||
while (attributes != null) {
|
while (attributes != null) {
|
||||||
@@ -697,6 +721,8 @@ public class ClassReader {
|
|||||||
String signature = null;
|
String signature = null;
|
||||||
int anns = 0;
|
int anns = 0;
|
||||||
int ianns = 0;
|
int ianns = 0;
|
||||||
|
int tanns = 0;
|
||||||
|
int itanns = 0;
|
||||||
Object value = null;
|
Object value = null;
|
||||||
Attribute attributes = null;
|
Attribute attributes = null;
|
||||||
|
|
||||||
@@ -717,9 +743,15 @@ public class ClassReader {
|
|||||||
} else if (ANNOTATIONS
|
} else if (ANNOTATIONS
|
||||||
&& "RuntimeVisibleAnnotations".equals(attrName)) {
|
&& "RuntimeVisibleAnnotations".equals(attrName)) {
|
||||||
anns = u + 8;
|
anns = u + 8;
|
||||||
|
} else if (ANNOTATIONS
|
||||||
|
&& "RuntimeVisibleTypeAnnotations".equals(attrName)) {
|
||||||
|
tanns = u + 8;
|
||||||
} else if (ANNOTATIONS
|
} else if (ANNOTATIONS
|
||||||
&& "RuntimeInvisibleAnnotations".equals(attrName)) {
|
&& "RuntimeInvisibleAnnotations".equals(attrName)) {
|
||||||
ianns = u + 8;
|
ianns = u + 8;
|
||||||
|
} else if (ANNOTATIONS
|
||||||
|
&& "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
|
||||||
|
itanns = u + 8;
|
||||||
} else {
|
} else {
|
||||||
Attribute attr = readAttribute(context.attrs, attrName, u + 8,
|
Attribute attr = readAttribute(context.attrs, attrName, u + 8,
|
||||||
readInt(u + 4), c, -1, null);
|
readInt(u + 4), c, -1, null);
|
||||||
@@ -739,7 +771,7 @@ public class ClassReader {
|
|||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
// visits the field annotations
|
// visits the field annotations and type annotations
|
||||||
if (ANNOTATIONS && anns != 0) {
|
if (ANNOTATIONS && anns != 0) {
|
||||||
for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
|
for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
|
||||||
v = readAnnotationValues(v + 2, c, true,
|
v = readAnnotationValues(v + 2, c, true,
|
||||||
@@ -752,6 +784,22 @@ public class ClassReader {
|
|||||||
fv.visitAnnotation(readUTF8(v, c), false));
|
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
|
// visits the field attributes
|
||||||
while (attributes != null) {
|
while (attributes != null) {
|
||||||
@@ -782,9 +830,9 @@ public class ClassReader {
|
|||||||
final Context context, int u) {
|
final Context context, int u) {
|
||||||
// reads the method declaration
|
// reads the method declaration
|
||||||
char[] c = context.buffer;
|
char[] c = context.buffer;
|
||||||
int access = readUnsignedShort(u);
|
context.access = readUnsignedShort(u);
|
||||||
String name = readUTF8(u + 2, c);
|
context.name = readUTF8(u + 2, c);
|
||||||
String desc = readUTF8(u + 4, c);
|
context.desc = readUTF8(u + 4, c);
|
||||||
u += 6;
|
u += 6;
|
||||||
|
|
||||||
// reads the method attributes
|
// reads the method attributes
|
||||||
@@ -792,8 +840,11 @@ public class ClassReader {
|
|||||||
int exception = 0;
|
int exception = 0;
|
||||||
String[] exceptions = null;
|
String[] exceptions = null;
|
||||||
String signature = null;
|
String signature = null;
|
||||||
|
int methodParameters = 0;
|
||||||
int anns = 0;
|
int anns = 0;
|
||||||
int ianns = 0;
|
int ianns = 0;
|
||||||
|
int tanns = 0;
|
||||||
|
int itanns = 0;
|
||||||
int dann = 0;
|
int dann = 0;
|
||||||
int mpanns = 0;
|
int mpanns = 0;
|
||||||
int impanns = 0;
|
int impanns = 0;
|
||||||
@@ -818,24 +869,32 @@ public class ClassReader {
|
|||||||
} else if (SIGNATURES && "Signature".equals(attrName)) {
|
} else if (SIGNATURES && "Signature".equals(attrName)) {
|
||||||
signature = readUTF8(u + 8, c);
|
signature = readUTF8(u + 8, c);
|
||||||
} else if ("Deprecated".equals(attrName)) {
|
} else if ("Deprecated".equals(attrName)) {
|
||||||
access |= Opcodes.ACC_DEPRECATED;
|
context.access |= Opcodes.ACC_DEPRECATED;
|
||||||
} else if (ANNOTATIONS
|
} else if (ANNOTATIONS
|
||||||
&& "RuntimeVisibleAnnotations".equals(attrName)) {
|
&& "RuntimeVisibleAnnotations".equals(attrName)) {
|
||||||
anns = u + 8;
|
anns = u + 8;
|
||||||
|
} else if (ANNOTATIONS
|
||||||
|
&& "RuntimeVisibleTypeAnnotations".equals(attrName)) {
|
||||||
|
tanns = u + 8;
|
||||||
} else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
|
} else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
|
||||||
dann = u + 8;
|
dann = u + 8;
|
||||||
} else if ("Synthetic".equals(attrName)) {
|
} else if ("Synthetic".equals(attrName)) {
|
||||||
access |= Opcodes.ACC_SYNTHETIC
|
context.access |= Opcodes.ACC_SYNTHETIC
|
||||||
| ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
|
| ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
|
||||||
} else if (ANNOTATIONS
|
} else if (ANNOTATIONS
|
||||||
&& "RuntimeInvisibleAnnotations".equals(attrName)) {
|
&& "RuntimeInvisibleAnnotations".equals(attrName)) {
|
||||||
ianns = u + 8;
|
ianns = u + 8;
|
||||||
|
} else if (ANNOTATIONS
|
||||||
|
&& "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
|
||||||
|
itanns = u + 8;
|
||||||
} else if (ANNOTATIONS
|
} else if (ANNOTATIONS
|
||||||
&& "RuntimeVisibleParameterAnnotations".equals(attrName)) {
|
&& "RuntimeVisibleParameterAnnotations".equals(attrName)) {
|
||||||
mpanns = u + 8;
|
mpanns = u + 8;
|
||||||
} else if (ANNOTATIONS
|
} else if (ANNOTATIONS
|
||||||
&& "RuntimeInvisibleParameterAnnotations".equals(attrName)) {
|
&& "RuntimeInvisibleParameterAnnotations".equals(attrName)) {
|
||||||
impanns = u + 8;
|
impanns = u + 8;
|
||||||
|
} else if ("MethodParameters".equals(attrName)) {
|
||||||
|
methodParameters = u + 8;
|
||||||
} else {
|
} else {
|
||||||
Attribute attr = readAttribute(context.attrs, attrName, u + 8,
|
Attribute attr = readAttribute(context.attrs, attrName, u + 8,
|
||||||
readInt(u + 4), c, -1, null);
|
readInt(u + 4), c, -1, null);
|
||||||
@@ -849,8 +908,8 @@ public class ClassReader {
|
|||||||
u += 2;
|
u += 2;
|
||||||
|
|
||||||
// visits the method declaration
|
// visits the method declaration
|
||||||
MethodVisitor mv = classVisitor.visitMethod(access, name, desc,
|
MethodVisitor mv = classVisitor.visitMethod(context.access,
|
||||||
signature, exceptions);
|
context.name, context.desc, signature, exceptions);
|
||||||
if (mv == null) {
|
if (mv == null) {
|
||||||
return u;
|
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
|
// visits the method annotations
|
||||||
if (ANNOTATIONS && dann != 0) {
|
if (ANNOTATIONS && dann != 0) {
|
||||||
AnnotationVisitor dv = mv.visitAnnotationDefault();
|
AnnotationVisitor dv = mv.visitAnnotationDefault();
|
||||||
@@ -914,11 +980,27 @@ public class ClassReader {
|
|||||||
mv.visitAnnotation(readUTF8(v, c), false));
|
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) {
|
if (ANNOTATIONS && mpanns != 0) {
|
||||||
readParameterAnnotations(mpanns, desc, c, true, mv);
|
readParameterAnnotations(mv, context, mpanns, true);
|
||||||
}
|
}
|
||||||
if (ANNOTATIONS && impanns != 0) {
|
if (ANNOTATIONS && impanns != 0) {
|
||||||
readParameterAnnotations(impanns, desc, c, false, mv);
|
readParameterAnnotations(mv, context, impanns, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// visits the method attributes
|
// visits the method attributes
|
||||||
@@ -931,9 +1013,6 @@ public class ClassReader {
|
|||||||
|
|
||||||
// visits the method code
|
// visits the method code
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
context.access = access;
|
|
||||||
context.name = name;
|
|
||||||
context.desc = desc;
|
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
readCode(mv, context, code);
|
readCode(mv, context, code);
|
||||||
}
|
}
|
||||||
@@ -966,7 +1045,7 @@ public class ClassReader {
|
|||||||
// reads the bytecode to find the labels
|
// reads the bytecode to find the labels
|
||||||
int codeStart = u;
|
int codeStart = u;
|
||||||
int codeEnd = u + codeLength;
|
int codeEnd = u + codeLength;
|
||||||
Label[] labels = new Label[codeLength + 2];
|
Label[] labels = context.labels = new Label[codeLength + 2];
|
||||||
readLabel(codeLength + 1, labels);
|
readLabel(codeLength + 1, labels);
|
||||||
while (u < codeEnd) {
|
while (u < codeEnd) {
|
||||||
int offset = u - codeStart;
|
int offset = u - codeStart;
|
||||||
@@ -1049,6 +1128,12 @@ public class ClassReader {
|
|||||||
u += 2;
|
u += 2;
|
||||||
|
|
||||||
// reads the code attributes
|
// 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 varTable = 0;
|
||||||
int varTypeTable = 0;
|
int varTypeTable = 0;
|
||||||
boolean zip = true;
|
boolean zip = true;
|
||||||
@@ -1089,6 +1174,16 @@ public class ClassReader {
|
|||||||
v += 4;
|
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)) {
|
} else if (FRAMES && "StackMapTable".equals(attrName)) {
|
||||||
if ((context.flags & SKIP_FRAMES) == 0) {
|
if ((context.flags & SKIP_FRAMES) == 0) {
|
||||||
stackMap = u + 10;
|
stackMap = u + 10;
|
||||||
@@ -1211,7 +1306,7 @@ public class ClassReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (frameCount > 0) {
|
if (frameCount > 0) {
|
||||||
stackMap = readFrame(stackMap, zip, unzip, labels, frame);
|
stackMap = readFrame(stackMap, zip, unzip, frame);
|
||||||
--frameCount;
|
--frameCount;
|
||||||
} else {
|
} else {
|
||||||
frame = null;
|
frame = null;
|
||||||
@@ -1358,6 +1453,29 @@ public class ClassReader {
|
|||||||
u += 4;
|
u += 4;
|
||||||
break;
|
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) {
|
if (labels[codeLength] != null) {
|
||||||
mv.visitLabel(labels[codeLength]);
|
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
|
// visits the code attributes
|
||||||
while (attributes != null) {
|
while (attributes != null) {
|
||||||
Attribute attr = attributes.next;
|
Attribute attr = attributes.next;
|
||||||
@@ -1409,25 +1553,176 @@ public class ClassReader {
|
|||||||
mv.visitMaxs(maxStack, maxLocals);
|
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.
|
* 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
|
* @param v
|
||||||
* start offset in {@link #b b} of the annotations to be read.
|
* 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
|
* @param visible
|
||||||
* <tt>true</tt> if the annotations to be read are visible at
|
* <tt>true</tt> if the annotations to be read are visible at
|
||||||
* runtime.
|
* runtime.
|
||||||
* @param mv
|
|
||||||
* the visitor that must visit the annotations.
|
|
||||||
*/
|
*/
|
||||||
private void readParameterAnnotations(int v, final String desc,
|
private void readParameterAnnotations(final MethodVisitor mv,
|
||||||
final char[] buf, final boolean visible, final MethodVisitor mv) {
|
final Context context, int v, final boolean visible) {
|
||||||
int i;
|
int i;
|
||||||
int n = b[v++] & 0xFF;
|
int n = b[v++] & 0xFF;
|
||||||
// workaround for a bug in javac (javac compiler generates a parameter
|
// 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
|
// equal to the number of parameters in the method descriptor - which
|
||||||
// includes the synthetic parameters added by the compiler). This work-
|
// includes the synthetic parameters added by the compiler). This work-
|
||||||
// around supposes that the synthetic parameters are the first ones.
|
// 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;
|
AnnotationVisitor av;
|
||||||
for (i = 0; i < synthetics; ++i) {
|
for (i = 0; i < synthetics; ++i) {
|
||||||
// virtual annotation to detect synthetic parameters in MethodWriter
|
// virtual annotation to detect synthetic parameters in MethodWriter
|
||||||
@@ -1445,12 +1740,13 @@ public class ClassReader {
|
|||||||
av.visitEnd();
|
av.visitEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
char[] c = context.buffer;
|
||||||
for (; i < n + synthetics; ++i) {
|
for (; i < n + synthetics; ++i) {
|
||||||
int j = readUnsignedShort(v);
|
int j = readUnsignedShort(v);
|
||||||
v += 2;
|
v += 2;
|
||||||
for (; j > 0; --j) {
|
for (; j > 0; --j) {
|
||||||
av = mv.visitParameterAnnotation(i, readUTF8(v, buf), visible);
|
av = mv.visitParameterAnnotation(i, readUTF8(v, c), visible);
|
||||||
v = readAnnotationValues(v + 2, buf, true, av);
|
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.
|
* if the stack map frame at stackMap is compressed or not.
|
||||||
* @param unzip
|
* @param unzip
|
||||||
* if the stack map frame must be uncompressed.
|
* 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
|
* @param frame
|
||||||
* where the parsed stack map frame must be stored.
|
* where the parsed stack map frame must be stored.
|
||||||
* @return the offset of the first byte following the parsed frame.
|
* @return the offset of the first byte following the parsed frame.
|
||||||
*/
|
*/
|
||||||
private int readFrame(int stackMap, boolean zip, boolean unzip,
|
private int readFrame(int stackMap, boolean zip, boolean unzip,
|
||||||
Label[] labels, Context frame) {
|
Context frame) {
|
||||||
char[] c = frame.buffer;
|
char[] c = frame.buffer;
|
||||||
|
Label[] labels = frame.labels;
|
||||||
int tag;
|
int tag;
|
||||||
int delta;
|
int delta;
|
||||||
if (zip) {
|
if (zip) {
|
||||||
@@ -1916,7 +2209,7 @@ public class ClassReader {
|
|||||||
* prototypes of the attributes that must be parsed during the
|
* prototypes of the attributes that must be parsed during the
|
||||||
* visit of the class. Any attribute whose type is not equal to
|
* visit of the class. Any attribute whose type is not equal to
|
||||||
* the type of one the prototypes is ignored (i.e. an empty
|
* 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
|
* @param type
|
||||||
* the type of the attribute.
|
* the type of the attribute.
|
||||||
* @param off
|
* @param off
|
||||||
@@ -1968,7 +2261,7 @@ public class ClassReader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the start index of the constant pool item in {@link #b b}, plus
|
* 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>
|
* normally not needed by class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param item
|
* @param item
|
||||||
@@ -1993,7 +2286,7 @@ public class ClassReader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a byte value in {@link #b b}. <i>This method is intended for
|
* 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>
|
* generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param index
|
* @param index
|
||||||
@@ -2006,7 +2299,7 @@ public class ClassReader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads an unsigned short value in {@link #b b}. <i>This method is intended
|
* 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>
|
* generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param index
|
* @param index
|
||||||
@@ -2020,7 +2313,7 @@ public class ClassReader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a signed short value in {@link #b b}. <i>This method is intended
|
* 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>
|
* generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param index
|
* @param index
|
||||||
@@ -2034,7 +2327,7 @@ public class ClassReader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a signed int value in {@link #b b}. <i>This method is intended for
|
* 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>
|
* generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param index
|
* @param index
|
||||||
@@ -2049,7 +2342,7 @@ public class ClassReader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a signed long value in {@link #b b}. <i>This method is intended for
|
* 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>
|
* generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param index
|
* @param index
|
||||||
@@ -2064,7 +2357,7 @@ public class ClassReader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads an UTF8 string constant pool item in {@link #b b}. <i>This method
|
* 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>
|
* by class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param index
|
* @param index
|
||||||
@@ -2139,7 +2432,7 @@ public class ClassReader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a class constant pool item in {@link #b b}. <i>This method is
|
* 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>
|
* class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param index
|
* @param index
|
||||||
@@ -2159,7 +2452,7 @@ public class ClassReader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a numeric or string constant pool item in {@link #b b}. <i>This
|
* 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>
|
* needed by class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param item
|
* @param item
|
||||||
|
|||||||
@@ -33,8 +33,9 @@ package org.objectweb.asm;
|
|||||||
* A visitor to visit a Java class. The methods of this class must be called in
|
* A visitor to visit a Java class. The methods of this class must be called in
|
||||||
* the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
|
* the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
|
||||||
* <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
|
* <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
|
||||||
* <tt>visitAttribute</tt> )* ( <tt>visitInnerClass</tt> | <tt>visitField</tt> |
|
* <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* (
|
||||||
* <tt>visitMethod</tt> )* <tt>visitEnd</tt>.
|
* <tt>visitInnerClass</tt> | <tt>visitField</tt> | <tt>visitMethod</tt> )*
|
||||||
|
* <tt>visitEnd</tt>.
|
||||||
*
|
*
|
||||||
* @author Eric Bruneton
|
* @author Eric Bruneton
|
||||||
*/
|
*/
|
||||||
@@ -42,7 +43,7 @@ public abstract class ClassVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The ASM API version implemented by this visitor. The value of this field
|
* 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;
|
protected final int api;
|
||||||
|
|
||||||
@@ -53,28 +54,28 @@ public abstract class ClassVisitor {
|
|||||||
protected ClassVisitor cv;
|
protected ClassVisitor cv;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.ClassVisitor}.
|
* Constructs a new {@link ClassVisitor}.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* the ASM API version implemented by this visitor. Must be one
|
* 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) {
|
public ClassVisitor(final int api) {
|
||||||
this(api, null);
|
this(api, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.ClassVisitor}.
|
* Constructs a new {@link ClassVisitor}.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* the ASM API version implemented by this visitor. Must be one
|
* 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
|
* @param cv
|
||||||
* the class visitor to which this visitor must delegate method
|
* the class visitor to which this visitor must delegate method
|
||||||
* calls. May be null.
|
* calls. May be null.
|
||||||
*/
|
*/
|
||||||
public ClassVisitor(final int api, final ClassVisitor cv) {
|
public ClassVisitor(final int api, final ClassVisitor cv) {
|
||||||
if (api != Opcodes.ASM4) {
|
if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
this.api = api;
|
this.api = api;
|
||||||
@@ -168,6 +169,39 @@ public abstract class ClassVisitor {
|
|||||||
return null;
|
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
|
||||||
|
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||||
|
* @param desc
|
||||||
|
* the class descriptor of the annotation class.
|
||||||
|
* @param visible
|
||||||
|
* <tt>true</tt> if the annotation is visible at runtime.
|
||||||
|
* @return a visitor to visit the annotation values, or <tt>null</tt> 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.
|
* Visits a non standard attribute of the class.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -30,10 +30,10 @@
|
|||||||
package org.objectweb.asm;
|
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
|
* 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",
|
* 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.
|
* to generate a modified class from one or more existing Java classes.
|
||||||
*
|
*
|
||||||
* @author Eric Bruneton
|
* @author Eric Bruneton
|
||||||
@@ -250,7 +250,7 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
static final int HANDLE_BASE = 20;
|
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
|
* instead of the constant pool, in order to avoid clashes with normal
|
||||||
* constant pool items in the ClassWriter constant pool's hash table.
|
* 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
|
* 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
|
* avoid clashes with normal constant pool items in the ClassWriter constant
|
||||||
* pool's hash table.
|
* pool's hash table.
|
||||||
*/
|
*/
|
||||||
static final int TYPE_UNINIT = 31;
|
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
|
* instead of the constant pool, in order to avoid clashes with normal
|
||||||
* constant pool items in the ClassWriter constant pool's hash table.
|
* constant pool items in the ClassWriter constant pool's hash table.
|
||||||
*/
|
*/
|
||||||
@@ -416,6 +416,16 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
*/
|
*/
|
||||||
private AnnotationWriter ianns;
|
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.
|
* The non standard attributes of this class.
|
||||||
*/
|
*/
|
||||||
@@ -477,12 +487,12 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
* <tt>true</tt> if the maximum stack size and number of local variables
|
* <tt>true</tt> if the maximum stack size and number of local variables
|
||||||
* must be automatically computed.
|
* must be automatically computed.
|
||||||
*/
|
*/
|
||||||
private final boolean computeMaxs;
|
private boolean computeMaxs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <tt>true</tt> if the stack map frames must be recomputed from scratch.
|
* <tt>true</tt> if the stack map frames must be recomputed from scratch.
|
||||||
*/
|
*/
|
||||||
private final boolean computeFrames;
|
private boolean computeFrames;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <tt>true</tt> if the stack map tables of this class are invalid. The
|
* <tt>true</tt> 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
|
* @param flags
|
||||||
* option flags that can be used to modify the default behavior
|
* option flags that can be used to modify the default behavior
|
||||||
@@ -595,7 +605,7 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
* {@link #COMPUTE_FRAMES}.
|
* {@link #COMPUTE_FRAMES}.
|
||||||
*/
|
*/
|
||||||
public ClassWriter(final int flags) {
|
public ClassWriter(final int flags) {
|
||||||
super(Opcodes.ASM4);
|
super(Opcodes.ASM5);
|
||||||
index = 1;
|
index = 1;
|
||||||
pool = new ByteVector();
|
pool = new ByteVector();
|
||||||
items = new Item[256];
|
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
|
* "mostly add" bytecode transformations. These optimizations are the
|
||||||
* following:
|
* following:
|
||||||
*
|
*
|
||||||
@@ -622,13 +632,13 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
* directly from the original class bytecode (i.e. without emitting visit
|
* directly from the original class bytecode (i.e. without emitting visit
|
||||||
* events for all the method instructions), which saves a <i>lot</i> of
|
* events for all the method instructions), which saves a <i>lot</i> of
|
||||||
* time. Untransformed methods are detected by the fact that the
|
* time. Untransformed methods are detected by the fact that the
|
||||||
* {@link org.objectweb.asm.ClassReader} receives {@link MethodVisitor} objects that come from
|
* {@link ClassReader} receives {@link MethodVisitor} objects that come from
|
||||||
* a {@link org.objectweb.asm.ClassWriter} (and not from any other {@link org.objectweb.asm.ClassVisitor}
|
* a {@link ClassWriter} (and not from any other {@link ClassVisitor}
|
||||||
* instance).</li>
|
* instance).</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @param classReader
|
* @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
|
* will be used to copy the entire constant pool from the
|
||||||
* original class and also to copy other fragments of original
|
* original class and also to copy other fragments of original
|
||||||
* bytecode where applicable.
|
* bytecode where applicable.
|
||||||
@@ -710,6 +720,29 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
return aw;
|
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
|
@Override
|
||||||
public final void visitAttribute(final Attribute attr) {
|
public final void visitAttribute(final Attribute attr) {
|
||||||
attr.next = attrs;
|
attr.next = attrs;
|
||||||
@@ -831,6 +864,16 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
size += 8 + ianns.getSize();
|
size += 8 + ianns.getSize();
|
||||||
newUTF8("RuntimeInvisibleAnnotations");
|
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) {
|
if (attrs != null) {
|
||||||
attributeCount += attrs.getCount();
|
attributeCount += attrs.getCount();
|
||||||
size += attrs.getSize(this, null, 0, -1, -1);
|
size += attrs.getSize(this, null, 0, -1, -1);
|
||||||
@@ -904,13 +947,34 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
|
out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
|
||||||
ianns.put(out);
|
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) {
|
if (attrs != null) {
|
||||||
attrs.put(this, null, 0, -1, -1, out);
|
attrs.put(this, null, 0, -1, -1, out);
|
||||||
}
|
}
|
||||||
if (invalidFrames) {
|
if (invalidFrames) {
|
||||||
ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
|
anns = null;
|
||||||
new ClassReader(out.data).accept(cw, ClassReader.SKIP_FRAMES);
|
ianns = null;
|
||||||
return cw.toByteArray();
|
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;
|
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
|
* 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.
|
* build. Does nothing if the constant pool already contains a similar item.
|
||||||
* <i>This method is intended for {@link org.objectweb.asm.Attribute} sub classes, and is
|
* <i>This method is intended for {@link Attribute} sub classes, and is
|
||||||
* normally not needed by class generators or adapters.</i>
|
* normally not needed by class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param cst
|
* @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
|
* Adds an UTF8 string to the constant pool of the class being build. Does
|
||||||
* nothing if the constant pool already contains a similar item. <i>This
|
* nothing if the constant pool already contains a similar item. <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>
|
* needed by class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param value
|
* @param value
|
||||||
@@ -1016,7 +1080,7 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
/**
|
/**
|
||||||
* Adds a class reference to the constant pool of the class being build.
|
* Adds a class reference to the constant pool of the class being build.
|
||||||
* Does nothing if the constant pool already contains a similar item.
|
* Does nothing if the constant pool already contains a similar item.
|
||||||
* <i>This method is intended for {@link org.objectweb.asm.Attribute} sub classes, and is
|
* <i>This method is intended for {@link Attribute} sub classes, and is
|
||||||
* normally not needed by class generators or adapters.</i>
|
* normally not needed by class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param value
|
* @param value
|
||||||
@@ -1037,7 +1101,7 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
/**
|
/**
|
||||||
* Adds a class reference to the constant pool of the class being build.
|
* Adds a class reference to the constant pool of the class being build.
|
||||||
* Does nothing if the constant pool already contains a similar item.
|
* Does nothing if the constant pool already contains a similar item.
|
||||||
* <i>This method is intended for {@link org.objectweb.asm.Attribute} sub classes, and is
|
* <i>This method is intended for {@link Attribute} sub classes, and is
|
||||||
* normally not needed by class generators or adapters.</i>
|
* normally not needed by class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param value
|
* @param value
|
||||||
@@ -1051,7 +1115,7 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
/**
|
/**
|
||||||
* Adds a method type reference to the constant pool of the class being
|
* 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.
|
* build. Does nothing if the constant pool already contains a similar item.
|
||||||
* <i>This method is intended for {@link org.objectweb.asm.Attribute} sub classes, and is
|
* <i>This method is intended for {@link Attribute} sub classes, and is
|
||||||
* normally not needed by class generators or adapters.</i>
|
* normally not needed by class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param methodDesc
|
* @param methodDesc
|
||||||
@@ -1072,7 +1136,7 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
/**
|
/**
|
||||||
* Adds a method type reference to the constant pool of the class being
|
* 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.
|
* build. Does nothing if the constant pool already contains a similar item.
|
||||||
* <i>This method is intended for {@link org.objectweb.asm.Attribute} sub classes, and is
|
* <i>This method is intended for {@link Attribute} sub classes, and is
|
||||||
* normally not needed by class generators or adapters.</i>
|
* normally not needed by class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param methodDesc
|
* @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
|
* Adds a handle to the constant pool of the class being build. Does nothing
|
||||||
* if the constant pool already contains a similar item. <i>This method is
|
* if the constant pool already contains a similar item. <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>
|
* class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param tag
|
* @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
|
* Adds a handle to the constant pool of the class being build. Does nothing
|
||||||
* if the constant pool already contains a similar item. <i>This method is
|
* if the constant pool already contains a similar item. <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>
|
* class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param tag
|
* @param tag
|
||||||
@@ -1156,7 +1220,7 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
/**
|
/**
|
||||||
* Adds an invokedynamic reference to the constant pool of the class being
|
* Adds an invokedynamic reference to the constant pool of the class being
|
||||||
* build. Does nothing if the constant pool already contains a similar item.
|
* build. Does nothing if the constant pool already contains a similar item.
|
||||||
* <i>This method is intended for {@link org.objectweb.asm.Attribute} sub classes, and is
|
* <i>This method is intended for {@link Attribute} sub classes, and is
|
||||||
* normally not needed by class generators or adapters.</i>
|
* normally not needed by class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param name
|
* @param name
|
||||||
@@ -1240,7 +1304,7 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
/**
|
/**
|
||||||
* Adds an invokedynamic reference to the constant pool of the class being
|
* Adds an invokedynamic reference to the constant pool of the class being
|
||||||
* build. Does nothing if the constant pool already contains a similar item.
|
* build. Does nothing if the constant pool already contains a similar item.
|
||||||
* <i>This method is intended for {@link org.objectweb.asm.Attribute} sub classes, and is
|
* <i>This method is intended for {@link Attribute} sub classes, and is
|
||||||
* normally not needed by class generators or adapters.</i>
|
* normally not needed by class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param name
|
* @param name
|
||||||
@@ -1286,7 +1350,7 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
/**
|
/**
|
||||||
* Adds a field reference to the constant pool of the class being build.
|
* Adds a field reference to the constant pool of the class being build.
|
||||||
* Does nothing if the constant pool already contains a similar item.
|
* Does nothing if the constant pool already contains a similar item.
|
||||||
* <i>This method is intended for {@link org.objectweb.asm.Attribute} sub classes, and is
|
* <i>This method is intended for {@link Attribute} sub classes, and is
|
||||||
* normally not needed by class generators or adapters.</i>
|
* normally not needed by class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param owner
|
* @param owner
|
||||||
@@ -1331,7 +1395,7 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
/**
|
/**
|
||||||
* Adds a method reference to the constant pool of the class being build.
|
* Adds a method reference to the constant pool of the class being build.
|
||||||
* Does nothing if the constant pool already contains a similar item.
|
* Does nothing if the constant pool already contains a similar item.
|
||||||
* <i>This method is intended for {@link org.objectweb.asm.Attribute} sub classes, and is
|
* <i>This method is intended for {@link Attribute} sub classes, and is
|
||||||
* normally not needed by class generators or adapters.</i>
|
* normally not needed by class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param owner
|
* @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
|
* 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. <i>This
|
* nothing if the constant pool already contains a similar item. <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>
|
* needed by class generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @param name
|
* @param name
|
||||||
@@ -1577,7 +1641,7 @@ public class ClassWriter extends ClassVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the common super type of the two given types. The default
|
* Returns the common super type of the two given types. The default
|
||||||
* implementation of this method <i>loads<i> the two given classes and uses
|
* implementation of this method <i>loads</i> the two given classes and uses
|
||||||
* the java.lang.Class methods to find the common super class. It can be
|
* 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
|
* overridden to compute this common super type in other ways, in particular
|
||||||
* without actually loading any class, or to take into account the class
|
* without actually loading any class, or to take into account the class
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
package org.objectweb.asm;
|
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
|
* @author Eric Bruneton
|
||||||
*/
|
*/
|
||||||
@@ -43,7 +43,7 @@ class Context {
|
|||||||
Attribute[] attrs;
|
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;
|
int flags;
|
||||||
|
|
||||||
@@ -72,11 +72,46 @@ class Context {
|
|||||||
*/
|
*/
|
||||||
String desc;
|
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.
|
* The offset of the latest stack map frame that has been parsed.
|
||||||
*/
|
*/
|
||||||
int offset;
|
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.
|
* The encoding of the latest stack map frame that has been parsed.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -43,20 +43,20 @@ class Edge {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Denotes a control flow graph edge corresponding to an exception handler.
|
* 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
|
* 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.
|
* is catched.
|
||||||
*/
|
*/
|
||||||
static final int EXCEPTION = 0x7FFFFFFF;
|
static final int EXCEPTION = 0x7FFFFFFF;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about this control flow graph edge. If
|
* 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
|
* 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
|
* 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
|
* 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
|
* this field is the kind of this control flow graph edge (i.e. NORMAL or
|
||||||
* EXCEPTION).
|
* EXCEPTION).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ package org.objectweb.asm;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A visitor to visit a Java field. The methods of this class must be called in
|
* A visitor to visit a Java field. The methods of this class must be called in
|
||||||
* the following order: ( <tt>visitAnnotation</tt> | <tt>visitAttribute</tt> )*
|
* the following order: ( <tt>visitAnnotation</tt> |
|
||||||
* <tt>visitEnd</tt>.
|
* <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* <tt>visitEnd</tt>.
|
||||||
*
|
*
|
||||||
* @author Eric Bruneton
|
* @author Eric Bruneton
|
||||||
*/
|
*/
|
||||||
@@ -40,7 +40,7 @@ public abstract class FieldVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The ASM API version implemented by this visitor. The value of this field
|
* 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;
|
protected final int api;
|
||||||
|
|
||||||
@@ -51,28 +51,28 @@ public abstract class FieldVisitor {
|
|||||||
protected FieldVisitor fv;
|
protected FieldVisitor fv;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.FieldVisitor}.
|
* Constructs a new {@link FieldVisitor}.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* the ASM API version implemented by this visitor. Must be one
|
* 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) {
|
public FieldVisitor(final int api) {
|
||||||
this(api, null);
|
this(api, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.FieldVisitor}.
|
* Constructs a new {@link FieldVisitor}.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* the ASM API version implemented by this visitor. Must be one
|
* 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
|
* @param fv
|
||||||
* the field visitor to which this visitor must delegate method
|
* the field visitor to which this visitor must delegate method
|
||||||
* calls. May be null.
|
* calls. May be null.
|
||||||
*/
|
*/
|
||||||
public FieldVisitor(final int api, final FieldVisitor fv) {
|
public FieldVisitor(final int api, final FieldVisitor fv) {
|
||||||
if (api != Opcodes.ASM4) {
|
if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
this.api = api;
|
this.api = api;
|
||||||
@@ -96,6 +96,35 @@ public abstract class FieldVisitor {
|
|||||||
return null;
|
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
|
||||||
|
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||||
|
* @param desc
|
||||||
|
* the class descriptor of the annotation class.
|
||||||
|
* @param visible
|
||||||
|
* <tt>true</tt> if the annotation is visible at runtime.
|
||||||
|
* @return a visitor to visit the annotation values, or <tt>null</tt> 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.
|
* Visits a non standard attribute of the field.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
package org.objectweb.asm;
|
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
|
* @author Eric Bruneton
|
||||||
*/
|
*/
|
||||||
@@ -80,6 +80,17 @@ final class FieldWriter extends FieldVisitor {
|
|||||||
*/
|
*/
|
||||||
private AnnotationWriter ianns;
|
private AnnotationWriter ianns;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runtime visible type annotations of this field. May be <tt>null</tt>.
|
||||||
|
*/
|
||||||
|
private AnnotationWriter tanns;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runtime invisible type annotations of this field. May be
|
||||||
|
* <tt>null</tt>.
|
||||||
|
*/
|
||||||
|
private AnnotationWriter itanns;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The non standard attributes of this field. May be <tt>null</tt>.
|
* The non standard attributes of this field. May be <tt>null</tt>.
|
||||||
*/
|
*/
|
||||||
@@ -90,7 +101,7 @@ final class FieldWriter extends FieldVisitor {
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.FieldWriter}.
|
* Constructs a new {@link FieldWriter}.
|
||||||
*
|
*
|
||||||
* @param cw
|
* @param cw
|
||||||
* the class writer to which this field must be added.
|
* 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,
|
FieldWriter(final ClassWriter cw, final int access, final String name,
|
||||||
final String desc, final String signature, final Object value) {
|
final String desc, final String signature, final Object value) {
|
||||||
super(Opcodes.ASM4);
|
super(Opcodes.ASM5);
|
||||||
if (cw.firstField == null) {
|
if (cw.firstField == null) {
|
||||||
cw.firstField = this;
|
cw.firstField = this;
|
||||||
} else {
|
} else {
|
||||||
@@ -150,6 +161,29 @@ final class FieldWriter extends FieldVisitor {
|
|||||||
return aw;
|
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
|
@Override
|
||||||
public void visitAttribute(final Attribute attr) {
|
public void visitAttribute(final Attribute attr) {
|
||||||
attr.next = attrs;
|
attr.next = attrs;
|
||||||
@@ -198,6 +232,14 @@ final class FieldWriter extends FieldVisitor {
|
|||||||
cw.newUTF8("RuntimeInvisibleAnnotations");
|
cw.newUTF8("RuntimeInvisibleAnnotations");
|
||||||
size += 8 + ianns.getSize();
|
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) {
|
if (attrs != null) {
|
||||||
size += attrs.getSize(cw, null, 0, -1, -1);
|
size += attrs.getSize(cw, null, 0, -1, -1);
|
||||||
}
|
}
|
||||||
@@ -237,6 +279,12 @@ final class FieldWriter extends FieldVisitor {
|
|||||||
if (ClassReader.ANNOTATIONS && ianns != null) {
|
if (ClassReader.ANNOTATIONS && ianns != null) {
|
||||||
++attributeCount;
|
++attributeCount;
|
||||||
}
|
}
|
||||||
|
if (ClassReader.ANNOTATIONS && tanns != null) {
|
||||||
|
++attributeCount;
|
||||||
|
}
|
||||||
|
if (ClassReader.ANNOTATIONS && itanns != null) {
|
||||||
|
++attributeCount;
|
||||||
|
}
|
||||||
if (attrs != null) {
|
if (attrs != null) {
|
||||||
attributeCount += attrs.getCount();
|
attributeCount += attrs.getCount();
|
||||||
}
|
}
|
||||||
@@ -266,6 +314,14 @@ final class FieldWriter extends FieldVisitor {
|
|||||||
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
|
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
|
||||||
ianns.put(out);
|
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) {
|
if (attrs != null) {
|
||||||
attrs.put(cw, null, 0, -1, -1, out);
|
attrs.put(cw, null, 0, -1, -1, out);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1278,8 +1278,8 @@ final class Frame {
|
|||||||
* @param frame
|
* @param frame
|
||||||
* the basic block whose input frame must be updated.
|
* the basic block whose input frame must be updated.
|
||||||
* @param edge
|
* @param edge
|
||||||
* the kind of the {@link org.objectweb.asm.Edge} between this label and 'label'.
|
* the kind of the {@link Edge} between this label and 'label'.
|
||||||
* See {@link org.objectweb.asm.Edge#info}.
|
* See {@link Edge#info}.
|
||||||
* @return <tt>true</tt> if the input frame of the given label has been
|
* @return <tt>true</tt> if the input frame of the given label has been
|
||||||
* changed by this operation.
|
* changed by this operation.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ public final class Handle {
|
|||||||
final int tag;
|
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;
|
final String owner;
|
||||||
|
|
||||||
@@ -76,8 +77,8 @@ public final class Handle {
|
|||||||
* {@link Opcodes#H_NEWINVOKESPECIAL} or
|
* {@link Opcodes#H_NEWINVOKESPECIAL} or
|
||||||
* {@link Opcodes#H_INVOKEINTERFACE}.
|
* {@link Opcodes#H_INVOKEINTERFACE}.
|
||||||
* @param owner
|
* @param owner
|
||||||
* the internal name of the field or method designed by this
|
* the internal name of the class that owns the field or method
|
||||||
* handle.
|
* designated by this handle.
|
||||||
* @param name
|
* @param name
|
||||||
* the name of the field or method designated by this handle.
|
* the name of the field or method designated by this handle.
|
||||||
* @param desc
|
* @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() {
|
public String getOwner() {
|
||||||
return owner;
|
return owner;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ package org.objectweb.asm;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A constant pool item. Constant pool items can be created with the 'newXXX'
|
* 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
|
* @author Eric Bruneton
|
||||||
*/
|
*/
|
||||||
@@ -45,24 +45,24 @@ final class Item {
|
|||||||
/**
|
/**
|
||||||
* Type of this constant pool item. A single class is used to represent all
|
* 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
|
* 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},
|
* package. The value of this field is one of {@link ClassWriter#INT},
|
||||||
* {@link org.objectweb.asm.ClassWriter#LONG}, {@link org.objectweb.asm.ClassWriter#FLOAT},
|
* {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT},
|
||||||
* {@link org.objectweb.asm.ClassWriter#DOUBLE}, {@link org.objectweb.asm.ClassWriter#UTF8},
|
* {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8},
|
||||||
* {@link org.objectweb.asm.ClassWriter#STR}, {@link org.objectweb.asm.ClassWriter#CLASS},
|
* {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
|
||||||
* {@link org.objectweb.asm.ClassWriter#NAME_TYPE}, {@link org.objectweb.asm.ClassWriter#FIELD},
|
* {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
|
||||||
* {@link org.objectweb.asm.ClassWriter#METH}, {@link org.objectweb.asm.ClassWriter#IMETH},
|
* {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
|
||||||
* {@link org.objectweb.asm.ClassWriter#MTYPE}, {@link org.objectweb.asm.ClassWriter#INDY}.
|
* {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
|
||||||
*
|
*
|
||||||
* MethodHandle constant 9 variations are stored using a range of 9 values
|
* MethodHandle constant 9 variations are stored using a range of 9 values
|
||||||
* from {@link org.objectweb.asm.ClassWriter#HANDLE_BASE} + 1 to
|
* from {@link ClassWriter#HANDLE_BASE} + 1 to
|
||||||
* {@link org.objectweb.asm.ClassWriter#HANDLE_BASE} + 9.
|
* {@link ClassWriter#HANDLE_BASE} + 9.
|
||||||
*
|
*
|
||||||
* Special Item types are used for Items that are stored in the ClassWriter
|
* 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
|
* avoid clashes with normal constant pool items in the ClassWriter constant
|
||||||
* pool's hash table. These special item types are
|
* 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 ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and
|
||||||
* {@link org.objectweb.asm.ClassWriter#TYPE_MERGED}.
|
* {@link ClassWriter#TYPE_MERGED}.
|
||||||
*/
|
*/
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
@@ -106,13 +106,13 @@ final class Item {
|
|||||||
Item next;
|
Item next;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an uninitialized {@link org.objectweb.asm.Item}.
|
* Constructs an uninitialized {@link Item}.
|
||||||
*/
|
*/
|
||||||
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.
|
* given position.
|
||||||
*
|
*
|
||||||
* @param index
|
* @param index
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ public class Label {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about the input and output stack map frames of this basic
|
* 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.
|
* option is used.
|
||||||
*/
|
*/
|
||||||
Frame frame;
|
Frame frame;
|
||||||
@@ -222,7 +222,7 @@ public class Label {
|
|||||||
/**
|
/**
|
||||||
* The successor of this label, in the order they are visited. This linked
|
* The successor of this label, in the order they are visited. This linked
|
||||||
* list does not include labels used for debug info only. If
|
* 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
|
* does not contain successive labels that denote the same bytecode position
|
||||||
* (in this case only the first label appears in this list).
|
* (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
|
* 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
|
* are stored in a linked list of {@link Edge Edge} objects, linked to each
|
||||||
* other by their {@link org.objectweb.asm.Edge#next} field.
|
* other by their {@link Edge#next} field.
|
||||||
*/
|
*/
|
||||||
Edge successors;
|
Edge successors;
|
||||||
|
|
||||||
@@ -262,7 +262,7 @@ public class Label {
|
|||||||
/**
|
/**
|
||||||
* Returns the offset corresponding to this label. This offset is computed
|
* Returns the offset corresponding to this label. This offset is computed
|
||||||
* from the start of the method's bytecode. <i>This method is intended for
|
* from the start of the method's bytecode. <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>
|
* generators or adapters.</i>
|
||||||
*
|
*
|
||||||
* @return the offset corresponding to this label.
|
* @return the offset corresponding to this label.
|
||||||
|
|||||||
@@ -31,18 +31,24 @@ package org.objectweb.asm;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A visitor to visit a Java method. The methods of this class must be called in
|
* A visitor to visit a Java method. The methods of this class must be called in
|
||||||
* the following order: [ <tt>visitAnnotationDefault</tt> ] (
|
* the following order: ( <tt>visitParameter</tt> )* [
|
||||||
* <tt>visitAnnotation</tt> | <tt>visitParameterAnnotation</tt> |
|
* <tt>visitAnnotationDefault</tt> ] ( <tt>visitAnnotation</tt> |
|
||||||
* <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> |
|
* <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* [
|
||||||
* <tt>visit</tt><i>X</i>Insn</tt> | <tt>visitLabel</tt> |
|
* <tt>visitCode</tt> ( <tt>visitFrame</tt> | <tt>visit<i>X</i>Insn</tt> |
|
||||||
* <tt>visitTryCatchBlock</tt> | <tt>visitLocalVariable</tt> |
|
* <tt>visitLabel</tt> | <tt>visitInsnAnnotation</tt> |
|
||||||
|
* <tt>visitTryCatchBlock</tt> | <tt>visitTryCatchBlockAnnotation</tt> |
|
||||||
|
* <tt>visitLocalVariable</tt> | <tt>visitLocalVariableAnnotation</tt> |
|
||||||
* <tt>visitLineNumber</tt> )* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In
|
* <tt>visitLineNumber</tt> )* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In
|
||||||
* addition, the <tt>visit</tt><i>X</i>Insn</tt> and <tt>visitLabel</tt> methods
|
* addition, the <tt>visit<i>X</i>Insn</tt> and <tt>visitLabel</tt> methods must
|
||||||
* must be called in the sequential order of the bytecode instructions of the
|
* be called in the sequential order of the bytecode instructions of the visited
|
||||||
* visited code, <tt>visitTryCatchBlock</tt> must be called <i>before</i> the
|
* code, <tt>visitInsnAnnotation</tt> must be called <i>after</i> the annotated
|
||||||
* labels passed as arguments have been visited, and the
|
* instruction, <tt>visitTryCatchBlock</tt> must be called <i>before</i> the
|
||||||
* <tt>visitLocalVariable</tt> and <tt>visitLineNumber</tt> methods must be
|
* labels passed as arguments have been visited,
|
||||||
* called <i>after</i> the labels passed as arguments have been visited.
|
* <tt>visitTryCatchBlockAnnotation</tt> must be called <i>after</i> the
|
||||||
|
* corresponding try catch block has been visited, and the
|
||||||
|
* <tt>visitLocalVariable</tt>, <tt>visitLocalVariableAnnotation</tt> and
|
||||||
|
* <tt>visitLineNumber</tt> methods must be called <i>after</i> the labels
|
||||||
|
* passed as arguments have been visited.
|
||||||
*
|
*
|
||||||
* @author Eric Bruneton
|
* @author Eric Bruneton
|
||||||
*/
|
*/
|
||||||
@@ -50,7 +56,7 @@ public abstract class MethodVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The ASM API version implemented by this visitor. The value of this field
|
* 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;
|
protected final int api;
|
||||||
|
|
||||||
@@ -61,28 +67,28 @@ public abstract class MethodVisitor {
|
|||||||
protected MethodVisitor mv;
|
protected MethodVisitor mv;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.MethodVisitor}.
|
* Constructs a new {@link MethodVisitor}.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* the ASM API version implemented by this visitor. Must be one
|
* 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) {
|
public MethodVisitor(final int api) {
|
||||||
this(api, null);
|
this(api, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.MethodVisitor}.
|
* Constructs a new {@link MethodVisitor}.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* the ASM API version implemented by this visitor. Must be one
|
* 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
|
* @param mv
|
||||||
* the method visitor to which this visitor must delegate method
|
* the method visitor to which this visitor must delegate method
|
||||||
* calls. May be null.
|
* calls. May be null.
|
||||||
*/
|
*/
|
||||||
public MethodVisitor(final int api, final MethodVisitor mv) {
|
public MethodVisitor(final int api, final MethodVisitor mv) {
|
||||||
if (api != Opcodes.ASM4) {
|
if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
this.api = api;
|
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 <tt>ACC_FINAL</tt>,
|
||||||
|
* <tt>ACC_SYNTHETIC</tt> or/and <tt>ACC_MANDATED</tt> 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.
|
* Visits the default value of this annotation interface method.
|
||||||
*
|
*
|
||||||
@@ -127,6 +152,42 @@ public abstract class MethodVisitor {
|
|||||||
return null;
|
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
|
||||||
|
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||||
|
* @param desc
|
||||||
|
* the class descriptor of the annotation class.
|
||||||
|
* @param visible
|
||||||
|
* <tt>true</tt> if the annotation is visible at runtime.
|
||||||
|
* @return a visitor to visit the annotation values, or <tt>null</tt> 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.
|
* Visits an annotation of a parameter this method.
|
||||||
*
|
*
|
||||||
@@ -201,9 +262,11 @@ public abstract class MethodVisitor {
|
|||||||
* <li>{@link Opcodes#F_CHOP} representing frame with current locals are the
|
* <li>{@link Opcodes#F_CHOP} representing frame with current locals are the
|
||||||
* same as the locals in the previous frame, except that the last 1-3 locals
|
* same as the locals in the previous frame, except that the last 1-3 locals
|
||||||
* are absent and with the empty stack (<code>nLocals</code> is 1, 2 or 3).</li>
|
* are absent and with the empty stack (<code>nLocals</code> is 1, 2 or 3).</li>
|
||||||
* <li>{@link Opcodes#F_FULL} representing complete frame data.</li></li>
|
* <li>{@link Opcodes#F_FULL} representing complete frame data.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* </ul> <br>
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
* <br>
|
||||||
* In both cases the first frame, corresponding to the method's parameters
|
* 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
|
* 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
|
* 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
|
* @param bsmArgs
|
||||||
* the bootstrap method constant arguments. Each argument must be
|
* the bootstrap method constant arguments. Each argument must be
|
||||||
* an {@link Integer}, {@link Float}, {@link Long},
|
* 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
|
* value. This method is allowed to modify the content of the
|
||||||
* array so a caller should expect that this array may change.
|
* array so a caller should expect that this array may change.
|
||||||
*/
|
*/
|
||||||
@@ -431,7 +494,7 @@ public abstract class MethodVisitor {
|
|||||||
* just after it.
|
* just after it.
|
||||||
*
|
*
|
||||||
* @param label
|
* @param label
|
||||||
* a {@link org.objectweb.asm.Label Label} object.
|
* a {@link Label Label} object.
|
||||||
*/
|
*/
|
||||||
public void visitLabel(Label label) {
|
public void visitLabel(Label label) {
|
||||||
if (mv != null) {
|
if (mv != null) {
|
||||||
@@ -484,7 +547,7 @@ public abstract class MethodVisitor {
|
|||||||
* {@link Double}, a {@link String}, a {@link Type} of OBJECT or
|
* {@link Double}, a {@link String}, a {@link Type} of OBJECT or
|
||||||
* ARRAY sort for <tt>.class</tt> constants, for classes whose
|
* ARRAY sort for <tt>.class</tt> constants, for classes whose
|
||||||
* version is 49.0, a {@link Type} of METHOD sort or a
|
* 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.
|
* classes whose version is 51.0.
|
||||||
*/
|
*/
|
||||||
public void visitLdcInsn(Object cst) {
|
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
|
||||||
|
* <i>after</i> 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
|
||||||
|
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||||
|
* @param desc
|
||||||
|
* the class descriptor of the annotation class.
|
||||||
|
* @param visible
|
||||||
|
* <tt>true</tt> if the annotation is visible at runtime.
|
||||||
|
* @return a visitor to visit the annotation values, or <tt>null</tt> 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
|
// 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 <i>after</i> 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
|
||||||
|
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||||
|
* @param desc
|
||||||
|
* the class descriptor of the annotation class.
|
||||||
|
* @param visible
|
||||||
|
* <tt>true</tt> if the annotation is visible at runtime.
|
||||||
|
* @return a visitor to visit the annotation values, or <tt>null</tt> 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.
|
* 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
|
||||||
|
* <tt>null</tt> 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
|
||||||
|
* <tt>true</tt> if the annotation is visible at runtime.
|
||||||
|
* @return a visitor to visit the annotation values, or <tt>null</tt> 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.
|
* Visits a line number declaration.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
package org.objectweb.asm;
|
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
|
* method of this class appends the bytecode corresponding to the visited
|
||||||
* instruction to a byte vector, in the order these methods are called.
|
* instruction to a byte vector, in the order these methods are called.
|
||||||
*
|
*
|
||||||
@@ -191,6 +191,18 @@ class MethodWriter extends MethodVisitor {
|
|||||||
*/
|
*/
|
||||||
private AnnotationWriter ianns;
|
private AnnotationWriter ianns;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runtime visible type annotations of this method. May be <tt>null</tt>
|
||||||
|
* .
|
||||||
|
*/
|
||||||
|
private AnnotationWriter tanns;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runtime invisible type annotations of this method. May be
|
||||||
|
* <tt>null</tt>.
|
||||||
|
*/
|
||||||
|
private AnnotationWriter itanns;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The runtime visible parameter annotations of this method. May be
|
* The runtime visible parameter annotations of this method. May be
|
||||||
* <tt>null</tt>.
|
* <tt>null</tt>.
|
||||||
@@ -263,7 +275,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
* local variables start at index 3 and are followed by the operand stack
|
* local variables start at index 3 and are followed by the operand stack
|
||||||
* values. In summary frame[0] = offset, frame[1] = nLocal, frame[2] =
|
* values. In summary frame[0] = offset, frame[1] = nLocal, frame[2] =
|
||||||
* nStack, frame[3] = nLocal. All types are encoded as integers, with the
|
* 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;
|
private int[] frame;
|
||||||
|
|
||||||
@@ -282,6 +294,16 @@ class MethodWriter extends MethodVisitor {
|
|||||||
*/
|
*/
|
||||||
private Handler lastHandler;
|
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.
|
* Number of entries in the LocalVariableTable attribute.
|
||||||
*/
|
*/
|
||||||
@@ -312,6 +334,21 @@ class MethodWriter extends MethodVisitor {
|
|||||||
*/
|
*/
|
||||||
private ByteVector lineNumber;
|
private ByteVector lineNumber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The start offset of the last visited instruction.
|
||||||
|
*/
|
||||||
|
private int lastCodeOffset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runtime visible type annotations of the code. May be <tt>null</tt>.
|
||||||
|
*/
|
||||||
|
private AnnotationWriter ctanns;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runtime invisible type annotations of the code. May be <tt>null</tt>.
|
||||||
|
*/
|
||||||
|
private AnnotationWriter ictanns;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The non standard attributes of the method's code.
|
* 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,
|
* 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
|
* 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 Label#successor} field, in the order they are visited by
|
||||||
* {@link org.objectweb.asm.MethodVisitor#visitLabel}, and starting with the first basic
|
* {@link MethodVisitor#visitLabel}, and starting with the first basic
|
||||||
* block.
|
* block.
|
||||||
*/
|
*/
|
||||||
private Label labels;
|
private Label labels;
|
||||||
@@ -371,7 +408,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
* The (relative) stack size after the last visited instruction. This size
|
* 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
|
* 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
|
* 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 <tt>stackSize</tt>.
|
* plus <tt>stackSize</tt>.
|
||||||
*/
|
*/
|
||||||
private int stackSize;
|
private int stackSize;
|
||||||
@@ -380,7 +417,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
* The (relative) maximum stack size after the last visited instruction.
|
* The (relative) maximum stack size after the last visited instruction.
|
||||||
* This size is relative to the beginning of the current basic block, i.e.,
|
* 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
|
* 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 <tt>stackSize</tt>.
|
* block plus <tt>stackSize</tt>.
|
||||||
*/
|
*/
|
||||||
private int maxStackSize;
|
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
|
* @param cw
|
||||||
* the class writer in which the method must be added.
|
* 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 desc, final String signature,
|
||||||
final String[] exceptions, final boolean computeMaxs,
|
final String[] exceptions, final boolean computeMaxs,
|
||||||
final boolean computeFrames) {
|
final boolean computeFrames) {
|
||||||
super(Opcodes.ASM4);
|
super(Opcodes.ASM5);
|
||||||
if (cw.firstMethod == null) {
|
if (cw.firstMethod == null) {
|
||||||
cw.firstMethod = this;
|
cw.firstMethod = this;
|
||||||
} else {
|
} else {
|
||||||
@@ -461,6 +498,16 @@ class MethodWriter extends MethodVisitor {
|
|||||||
// Implementation of the MethodVisitor abstract class
|
// 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
|
@Override
|
||||||
public AnnotationVisitor visitAnnotationDefault() {
|
public AnnotationVisitor visitAnnotationDefault() {
|
||||||
if (!ClassReader.ANNOTATIONS) {
|
if (!ClassReader.ANNOTATIONS) {
|
||||||
@@ -490,6 +537,29 @@ class MethodWriter extends MethodVisitor {
|
|||||||
return aw;
|
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
|
@Override
|
||||||
public AnnotationVisitor visitParameterAnnotation(final int parameter,
|
public AnnotationVisitor visitParameterAnnotation(final int parameter,
|
||||||
final String desc, final boolean visible) {
|
final String desc, final boolean visible) {
|
||||||
@@ -642,6 +712,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitInsn(final int opcode) {
|
public void visitInsn(final int opcode) {
|
||||||
|
lastCodeOffset = code.length;
|
||||||
// adds the instruction to the bytecode of the method
|
// adds the instruction to the bytecode of the method
|
||||||
code.putByte(opcode);
|
code.putByte(opcode);
|
||||||
// update currentBlock
|
// update currentBlock
|
||||||
@@ -667,6 +738,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitIntInsn(final int opcode, final int operand) {
|
public void visitIntInsn(final int opcode, final int operand) {
|
||||||
|
lastCodeOffset = code.length;
|
||||||
// Label currentBlock = this.currentBlock;
|
// Label currentBlock = this.currentBlock;
|
||||||
if (currentBlock != null) {
|
if (currentBlock != null) {
|
||||||
if (compute == FRAMES) {
|
if (compute == FRAMES) {
|
||||||
@@ -691,6 +763,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitVarInsn(final int opcode, final int var) {
|
public void visitVarInsn(final int opcode, final int var) {
|
||||||
|
lastCodeOffset = code.length;
|
||||||
// Label currentBlock = this.currentBlock;
|
// Label currentBlock = this.currentBlock;
|
||||||
if (currentBlock != null) {
|
if (currentBlock != null) {
|
||||||
if (compute == FRAMES) {
|
if (compute == FRAMES) {
|
||||||
@@ -749,6 +822,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitTypeInsn(final int opcode, final String type) {
|
public void visitTypeInsn(final int opcode, final String type) {
|
||||||
|
lastCodeOffset = code.length;
|
||||||
Item i = cw.newClassItem(type);
|
Item i = cw.newClassItem(type);
|
||||||
// Label currentBlock = this.currentBlock;
|
// Label currentBlock = this.currentBlock;
|
||||||
if (currentBlock != null) {
|
if (currentBlock != null) {
|
||||||
@@ -771,6 +845,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visitFieldInsn(final int opcode, final String owner,
|
public void visitFieldInsn(final int opcode, final String owner,
|
||||||
final String name, final String desc) {
|
final String name, final String desc) {
|
||||||
|
lastCodeOffset = code.length;
|
||||||
Item i = cw.newFieldItem(owner, name, desc);
|
Item i = cw.newFieldItem(owner, name, desc);
|
||||||
// Label currentBlock = this.currentBlock;
|
// Label currentBlock = this.currentBlock;
|
||||||
if (currentBlock != null) {
|
if (currentBlock != null) {
|
||||||
@@ -809,6 +884,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visitMethodInsn(final int opcode, final String owner,
|
public void visitMethodInsn(final int opcode, final String owner,
|
||||||
final String name, final String desc) {
|
final String name, final String desc) {
|
||||||
|
lastCodeOffset = code.length;
|
||||||
boolean itf = opcode == Opcodes.INVOKEINTERFACE;
|
boolean itf = opcode == Opcodes.INVOKEINTERFACE;
|
||||||
Item i = cw.newMethodItem(owner, name, desc, itf);
|
Item i = cw.newMethodItem(owner, name, desc, itf);
|
||||||
int argSize = i.intVal;
|
int argSize = i.intVal;
|
||||||
@@ -861,6 +937,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visitInvokeDynamicInsn(final String name, final String desc,
|
public void visitInvokeDynamicInsn(final String name, final String desc,
|
||||||
final Handle bsm, final Object... bsmArgs) {
|
final Handle bsm, final Object... bsmArgs) {
|
||||||
|
lastCodeOffset = code.length;
|
||||||
Item i = cw.newInvokeDynamicItem(name, desc, bsm, bsmArgs);
|
Item i = cw.newInvokeDynamicItem(name, desc, bsm, bsmArgs);
|
||||||
int argSize = i.intVal;
|
int argSize = i.intVal;
|
||||||
// Label currentBlock = this.currentBlock;
|
// Label currentBlock = this.currentBlock;
|
||||||
@@ -900,6 +977,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitJumpInsn(final int opcode, final Label label) {
|
public void visitJumpInsn(final int opcode, final Label label) {
|
||||||
|
lastCodeOffset = code.length;
|
||||||
Label nextInsn = null;
|
Label nextInsn = null;
|
||||||
// Label currentBlock = this.currentBlock;
|
// Label currentBlock = this.currentBlock;
|
||||||
if (currentBlock != null) {
|
if (currentBlock != null) {
|
||||||
@@ -1045,6 +1123,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitLdcInsn(final Object cst) {
|
public void visitLdcInsn(final Object cst) {
|
||||||
|
lastCodeOffset = code.length;
|
||||||
Item i = cw.newConstItem(cst);
|
Item i = cw.newConstItem(cst);
|
||||||
// Label currentBlock = this.currentBlock;
|
// Label currentBlock = this.currentBlock;
|
||||||
if (currentBlock != null) {
|
if (currentBlock != null) {
|
||||||
@@ -1078,6 +1157,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitIincInsn(final int var, final int increment) {
|
public void visitIincInsn(final int var, final int increment) {
|
||||||
|
lastCodeOffset = code.length;
|
||||||
if (currentBlock != null) {
|
if (currentBlock != null) {
|
||||||
if (compute == FRAMES) {
|
if (compute == FRAMES) {
|
||||||
currentBlock.frame.execute(Opcodes.IINC, var, null, null);
|
currentBlock.frame.execute(Opcodes.IINC, var, null, null);
|
||||||
@@ -1102,6 +1182,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visitTableSwitchInsn(final int min, final int max,
|
public void visitTableSwitchInsn(final int min, final int max,
|
||||||
final Label dflt, final Label... labels) {
|
final Label dflt, final Label... labels) {
|
||||||
|
lastCodeOffset = code.length;
|
||||||
// adds the instruction to the bytecode of the method
|
// adds the instruction to the bytecode of the method
|
||||||
int source = code.length;
|
int source = code.length;
|
||||||
code.putByte(Opcodes.TABLESWITCH);
|
code.putByte(Opcodes.TABLESWITCH);
|
||||||
@@ -1118,6 +1199,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
|
public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
|
||||||
final Label[] labels) {
|
final Label[] labels) {
|
||||||
|
lastCodeOffset = code.length;
|
||||||
// adds the instruction to the bytecode of the method
|
// adds the instruction to the bytecode of the method
|
||||||
int source = code.length;
|
int source = code.length;
|
||||||
code.putByte(Opcodes.LOOKUPSWITCH);
|
code.putByte(Opcodes.LOOKUPSWITCH);
|
||||||
@@ -1160,6 +1242,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitMultiANewArrayInsn(final String desc, final int dims) {
|
public void visitMultiANewArrayInsn(final String desc, final int dims) {
|
||||||
|
lastCodeOffset = code.length;
|
||||||
Item i = cw.newClassItem(desc);
|
Item i = cw.newClassItem(desc);
|
||||||
// Label currentBlock = this.currentBlock;
|
// Label currentBlock = this.currentBlock;
|
||||||
if (currentBlock != null) {
|
if (currentBlock != null) {
|
||||||
@@ -1175,6 +1258,30 @@ class MethodWriter extends MethodVisitor {
|
|||||||
code.put12(Opcodes.MULTIANEWARRAY, i.index).putByte(dims);
|
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
|
@Override
|
||||||
public void visitTryCatchBlock(final Label start, final Label end,
|
public void visitTryCatchBlock(final Label start, final Label end,
|
||||||
final Label handler, final String type) {
|
final Label handler, final String type) {
|
||||||
@@ -1193,6 +1300,29 @@ class MethodWriter extends MethodVisitor {
|
|||||||
lastHandler = h;
|
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
|
@Override
|
||||||
public void visitLocalVariable(final String name, final String desc,
|
public void visitLocalVariable(final String name, final String desc,
|
||||||
final String signature, final Label start, final Label end,
|
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
|
@Override
|
||||||
public void visitLineNumber(final int line, final Label start) {
|
public void visitLineNumber(final int line, final Label start) {
|
||||||
if (lineNumber == null) {
|
if (lineNumber == null) {
|
||||||
@@ -1768,7 +1933,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
/**
|
/**
|
||||||
* Writes some types of the current frame {@link #frame} into the
|
* Writes some types of the current frame {@link #frame} into the
|
||||||
* StackMapTableAttribute. This method converts types from the format used
|
* 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.
|
* particular, it converts type table indexes to constant pool indexes.
|
||||||
*
|
*
|
||||||
* @param start
|
* @param start
|
||||||
@@ -1890,6 +2055,14 @@ class MethodWriter extends MethodVisitor {
|
|||||||
cw.newUTF8(zip ? "StackMapTable" : "StackMap");
|
cw.newUTF8(zip ? "StackMapTable" : "StackMap");
|
||||||
size += 8 + stackMap.length;
|
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) {
|
if (cattrs != null) {
|
||||||
size += cattrs.getSize(cw, code.data, code.length, maxStack,
|
size += cattrs.getSize(cw, code.data, code.length, maxStack,
|
||||||
maxLocals);
|
maxLocals);
|
||||||
@@ -1915,6 +2088,10 @@ class MethodWriter extends MethodVisitor {
|
|||||||
cw.newUTF8(signature);
|
cw.newUTF8(signature);
|
||||||
size += 8;
|
size += 8;
|
||||||
}
|
}
|
||||||
|
if (methodParameters != null) {
|
||||||
|
cw.newUTF8("MethodParameters");
|
||||||
|
size += 7 + methodParameters.length;
|
||||||
|
}
|
||||||
if (ClassReader.ANNOTATIONS && annd != null) {
|
if (ClassReader.ANNOTATIONS && annd != null) {
|
||||||
cw.newUTF8("AnnotationDefault");
|
cw.newUTF8("AnnotationDefault");
|
||||||
size += 6 + annd.length;
|
size += 6 + annd.length;
|
||||||
@@ -1927,6 +2104,14 @@ class MethodWriter extends MethodVisitor {
|
|||||||
cw.newUTF8("RuntimeInvisibleAnnotations");
|
cw.newUTF8("RuntimeInvisibleAnnotations");
|
||||||
size += 8 + ianns.getSize();
|
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) {
|
if (ClassReader.ANNOTATIONS && panns != null) {
|
||||||
cw.newUTF8("RuntimeVisibleParameterAnnotations");
|
cw.newUTF8("RuntimeVisibleParameterAnnotations");
|
||||||
size += 7 + 2 * (panns.length - synthetics);
|
size += 7 + 2 * (panns.length - synthetics);
|
||||||
@@ -1983,6 +2168,9 @@ class MethodWriter extends MethodVisitor {
|
|||||||
if (ClassReader.SIGNATURES && signature != null) {
|
if (ClassReader.SIGNATURES && signature != null) {
|
||||||
++attributeCount;
|
++attributeCount;
|
||||||
}
|
}
|
||||||
|
if (methodParameters != null) {
|
||||||
|
++attributeCount;
|
||||||
|
}
|
||||||
if (ClassReader.ANNOTATIONS && annd != null) {
|
if (ClassReader.ANNOTATIONS && annd != null) {
|
||||||
++attributeCount;
|
++attributeCount;
|
||||||
}
|
}
|
||||||
@@ -1992,6 +2180,12 @@ class MethodWriter extends MethodVisitor {
|
|||||||
if (ClassReader.ANNOTATIONS && ianns != null) {
|
if (ClassReader.ANNOTATIONS && ianns != null) {
|
||||||
++attributeCount;
|
++attributeCount;
|
||||||
}
|
}
|
||||||
|
if (ClassReader.ANNOTATIONS && tanns != null) {
|
||||||
|
++attributeCount;
|
||||||
|
}
|
||||||
|
if (ClassReader.ANNOTATIONS && itanns != null) {
|
||||||
|
++attributeCount;
|
||||||
|
}
|
||||||
if (ClassReader.ANNOTATIONS && panns != null) {
|
if (ClassReader.ANNOTATIONS && panns != null) {
|
||||||
++attributeCount;
|
++attributeCount;
|
||||||
}
|
}
|
||||||
@@ -2016,6 +2210,12 @@ class MethodWriter extends MethodVisitor {
|
|||||||
if (stackMap != null) {
|
if (stackMap != null) {
|
||||||
size += 8 + stackMap.length;
|
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) {
|
if (cattrs != null) {
|
||||||
size += cattrs.getSize(cw, code.data, code.length, maxStack,
|
size += cattrs.getSize(cw, code.data, code.length, maxStack,
|
||||||
maxLocals);
|
maxLocals);
|
||||||
@@ -2045,6 +2245,12 @@ class MethodWriter extends MethodVisitor {
|
|||||||
if (stackMap != null) {
|
if (stackMap != null) {
|
||||||
++attributeCount;
|
++attributeCount;
|
||||||
}
|
}
|
||||||
|
if (ClassReader.ANNOTATIONS && ctanns != null) {
|
||||||
|
++attributeCount;
|
||||||
|
}
|
||||||
|
if (ClassReader.ANNOTATIONS && ictanns != null) {
|
||||||
|
++attributeCount;
|
||||||
|
}
|
||||||
if (cattrs != null) {
|
if (cattrs != null) {
|
||||||
attributeCount += cattrs.getCount();
|
attributeCount += cattrs.getCount();
|
||||||
}
|
}
|
||||||
@@ -2070,6 +2276,14 @@ class MethodWriter extends MethodVisitor {
|
|||||||
out.putInt(stackMap.length + 2).putShort(frameCount);
|
out.putInt(stackMap.length + 2).putShort(frameCount);
|
||||||
out.putByteArray(stackMap.data, 0, stackMap.length);
|
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) {
|
if (cattrs != null) {
|
||||||
cattrs.put(cw, code.data, code.length, maxLocals, maxStack, out);
|
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)
|
out.putShort(cw.newUTF8("Signature")).putInt(2)
|
||||||
.putShort(cw.newUTF8(signature));
|
.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) {
|
if (ClassReader.ANNOTATIONS && annd != null) {
|
||||||
out.putShort(cw.newUTF8("AnnotationDefault"));
|
out.putShort(cw.newUTF8("AnnotationDefault"));
|
||||||
out.putInt(annd.length);
|
out.putInt(annd.length);
|
||||||
@@ -2108,6 +2328,14 @@ class MethodWriter extends MethodVisitor {
|
|||||||
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
|
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
|
||||||
ianns.put(out);
|
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) {
|
if (ClassReader.ANNOTATIONS && panns != null) {
|
||||||
out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations"));
|
out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations"));
|
||||||
AnnotationWriter.put(panns, synthetics, out);
|
AnnotationWriter.put(panns, synthetics, out);
|
||||||
@@ -2127,7 +2355,7 @@ class MethodWriter extends MethodVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Resizes and replaces the temporary instructions inserted by
|
* 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
|
* and instruction addresses consistent. This may require to resize other
|
||||||
* existing instructions, or even to introduce new instructions: for
|
* existing instructions, or even to introduce new instructions: for
|
||||||
* example, increasing the size of an instruction by 2 at the middle of a
|
* 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.
|
* by this method.
|
||||||
* <p>
|
* <p>
|
||||||
* <i>This method must be called after all the method that is being built
|
* <i>This method must be called after all the method that is being built
|
||||||
* has been visited</i>. In particular, the {@link org.objectweb.asm.Label Label} objects used
|
* has been visited</i>. In particular, the {@link Label Label} objects used
|
||||||
* to construct the method are no longer valid after this method has been
|
* to construct the method are no longer valid after this method has been
|
||||||
* called.
|
* called.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public interface Opcodes {
|
|||||||
// ASM API versions
|
// ASM API versions
|
||||||
|
|
||||||
int ASM4 = 4 << 16 | 0 << 8 | 0;
|
int ASM4 = 4 << 16 | 0 << 8 | 0;
|
||||||
|
int ASM5 = 5 << 16 | 0 << 8 | 0;
|
||||||
|
|
||||||
// versions
|
// versions
|
||||||
|
|
||||||
@@ -56,6 +57,7 @@ public interface Opcodes {
|
|||||||
int V1_5 = 0 << 16 | 49;
|
int V1_5 = 0 << 16 | 49;
|
||||||
int V1_6 = 0 << 16 | 50;
|
int V1_6 = 0 << 16 | 50;
|
||||||
int V1_7 = 0 << 16 | 51;
|
int V1_7 = 0 << 16 | 51;
|
||||||
|
int V1_8 = 0 << 16 | 52;
|
||||||
|
|
||||||
// access flags
|
// access flags
|
||||||
|
|
||||||
@@ -63,7 +65,7 @@ public interface Opcodes {
|
|||||||
int ACC_PRIVATE = 0x0002; // class, field, method
|
int ACC_PRIVATE = 0x0002; // class, field, method
|
||||||
int ACC_PROTECTED = 0x0004; // class, field, method
|
int ACC_PROTECTED = 0x0004; // class, field, method
|
||||||
int ACC_STATIC = 0x0008; // 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_SUPER = 0x0020; // class
|
||||||
int ACC_SYNCHRONIZED = 0x0020; // method
|
int ACC_SYNCHRONIZED = 0x0020; // method
|
||||||
int ACC_VOLATILE = 0x0040; // field
|
int ACC_VOLATILE = 0x0040; // field
|
||||||
@@ -74,9 +76,10 @@ public interface Opcodes {
|
|||||||
int ACC_INTERFACE = 0x0200; // class
|
int ACC_INTERFACE = 0x0200; // class
|
||||||
int ACC_ABSTRACT = 0x0400; // class, method
|
int ACC_ABSTRACT = 0x0400; // class, method
|
||||||
int ACC_STRICT = 0x0800; // 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_ANNOTATION = 0x2000; // class
|
||||||
int ACC_ENUM = 0x4000; // class(?) field inner
|
int ACC_ENUM = 0x4000; // class(?) field inner
|
||||||
|
int ACC_MANDATED = 0x8000; // parameter
|
||||||
|
|
||||||
// ASM specific pseudo access flags
|
// ASM specific pseudo access flags
|
||||||
|
|
||||||
@@ -108,7 +111,7 @@ public interface Opcodes {
|
|||||||
// stack map frame types
|
// 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;
|
int F_NEW = -1;
|
||||||
|
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ public class Type {
|
|||||||
* Returns the Java method type corresponding to the given constructor.
|
* Returns the Java method type corresponding to the given constructor.
|
||||||
*
|
*
|
||||||
* @param c
|
* @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.
|
* @return the Java method type corresponding to the given constructor.
|
||||||
*/
|
*/
|
||||||
public static Type getType(final Constructor<?> c) {
|
public static Type getType(final Constructor<?> c) {
|
||||||
@@ -305,7 +305,7 @@ public class Type {
|
|||||||
* Returns the Java method type corresponding to the given method.
|
* Returns the Java method type corresponding to the given method.
|
||||||
*
|
*
|
||||||
* @param m
|
* @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.
|
* @return the Java method type corresponding to the given method.
|
||||||
*/
|
*/
|
||||||
public static Type getType(final Method m) {
|
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
|
* @return the size of the arguments of the method (plus one for the
|
||||||
* implicit this argument), argSize, and the size of its return
|
* implicit this argument), argSize, and the size of its return
|
||||||
* value, retSize, packed into a single int i =
|
* value, retSize, packed into a single int i =
|
||||||
* <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal to
|
* <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal to
|
||||||
* <tt>i >> 2</tt>, and retSize to <tt>i & 0x03</tt>).
|
* <tt>i >> 2</tt>, and retSize to <tt>i & 0x03</tt>).
|
||||||
*/
|
*/
|
||||||
public static int getArgumentsAndReturnSizes(final String desc) {
|
public static int getArgumentsAndReturnSizes(final String desc) {
|
||||||
int n = 1;
|
int n = 1;
|
||||||
@@ -606,9 +606,10 @@ public class Type {
|
|||||||
*
|
*
|
||||||
* @return the size of the arguments (plus one for the implicit this
|
* @return the size of the arguments (plus one for the implicit this
|
||||||
* argument), argSize, and the size of the return value, retSize,
|
* argument), argSize, and the size of the return value, retSize,
|
||||||
* packed into a single int i = <tt>(argSize << 2) | retSize</tt>
|
* packed into a single
|
||||||
* (argSize is therefore equal to <tt>i >> 2</tt>, and retSize to
|
* int i = <tt>(argSize << 2) | retSize</tt>
|
||||||
* <tt>i & 0x03</tt>).
|
* (argSize is therefore equal to <tt>i >> 2</tt>,
|
||||||
|
* and retSize to <tt>i & 0x03</tt>).
|
||||||
*/
|
*/
|
||||||
public int getArgumentsAndReturnSizes() {
|
public int getArgumentsAndReturnSizes() {
|
||||||
return getArgumentsAndReturnSizes(getDescriptor());
|
return getArgumentsAndReturnSizes(getDescriptor());
|
||||||
@@ -708,7 +709,7 @@ public class Type {
|
|||||||
* Returns the descriptor corresponding to the given constructor.
|
* Returns the descriptor corresponding to the given constructor.
|
||||||
*
|
*
|
||||||
* @param c
|
* @param c
|
||||||
* a {@link java.lang.reflect.Constructor Constructor} object.
|
* a {@link Constructor Constructor} object.
|
||||||
* @return the descriptor of the given constructor.
|
* @return the descriptor of the given constructor.
|
||||||
*/
|
*/
|
||||||
public static String getConstructorDescriptor(final Constructor<?> c) {
|
public static String getConstructorDescriptor(final Constructor<?> c) {
|
||||||
@@ -725,7 +726,7 @@ public class Type {
|
|||||||
* Returns the descriptor corresponding to the given method.
|
* Returns the descriptor corresponding to the given method.
|
||||||
*
|
*
|
||||||
* @param m
|
* @param m
|
||||||
* a {@link java.lang.reflect.Method Method} object.
|
* a {@link Method Method} object.
|
||||||
* @return the descriptor of the given method.
|
* @return the descriptor of the given method.
|
||||||
*/
|
*/
|
||||||
public static String getMethodDescriptor(final Method m) {
|
public static String getMethodDescriptor(final Method m) {
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
<html>
|
|
||||||
<!--
|
|
||||||
* ASM: a very small and fast Java bytecode manipulation framework
|
|
||||||
* Copyright (c) 2000-2011 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.
|
|
||||||
-->
|
|
||||||
<body>
|
|
||||||
Provides a small and fast bytecode manipulation framework.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The <a href="http://www.objectweb.org/asm">ASM</a> 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.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
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.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
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 visit<i>Xxx</i>
|
|
||||||
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.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
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.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The size of the core ASM library, <tt>asm.jar</tt>, is only 45KB, which is much
|
|
||||||
smaller than the size of the
|
|
||||||
<a href="http://jakarta.apache.org/bcel">BCEL</a> library (504KB), and than the
|
|
||||||
size of the
|
|
||||||
<a href="http://serp.sourceforge.net">SERP</a> 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 <tt>test/perf</tt> directory in the ASM
|
|
||||||
distribution)!
|
|
||||||
|
|
||||||
@since ASM 1.3
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -44,7 +44,7 @@ public class SignatureReader {
|
|||||||
private final String signature;
|
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
|
* @param signature
|
||||||
* A <i>ClassSignature</i>, <i>MethodTypeSignature</i>, or
|
* A <i>ClassSignature</i>, <i>MethodTypeSignature</i>, or
|
||||||
@@ -56,9 +56,9 @@ public class SignatureReader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the given visitor visit the signature of this
|
* 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
|
* 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 <i>ClassSignature</i> (such as the <code>signature</code>
|
* created using a <i>ClassSignature</i> (such as the <code>signature</code>
|
||||||
* parameter of the {@link org.objectweb.asm.ClassVisitor#visit
|
* parameter of the {@link org.objectweb.asm.ClassVisitor#visit
|
||||||
* ClassVisitor.visit} method) or a <i>MethodTypeSignature</i> (such as the
|
* ClassVisitor.visit} method) or a <i>MethodTypeSignature</i> (such as the
|
||||||
@@ -114,9 +114,9 @@ public class SignatureReader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the given visitor visit the signature of this
|
* 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
|
* 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 <i>FieldTypeSignature</i>, such as the
|
* created using a <i>FieldTypeSignature</i>, such as the
|
||||||
* <code>signature</code> parameter of the
|
* <code>signature</code> parameter of the
|
||||||
* {@link org.objectweb.asm.ClassVisitor#visitField ClassVisitor.visitField}
|
* {@link org.objectweb.asm.ClassVisitor#visitField ClassVisitor.visitField}
|
||||||
|
|||||||
@@ -29,10 +29,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.objectweb.asm.signature;
|
package org.objectweb.asm.signature;
|
||||||
|
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A visitor to visit a generic signature. The methods of this interface must be
|
* 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
|
* 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):
|
* interface):
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><i>ClassSignature</i> = ( <tt>visitFormalTypeParameter</tt>
|
* <li><i>ClassSignature</i> = ( <tt>visitFormalTypeParameter</tt>
|
||||||
@@ -71,18 +73,21 @@ public abstract class SignatureVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The ASM API version implemented by this visitor. The value of this field
|
* The ASM API version implemented by this visitor. The value of this field
|
||||||
* must be one of {@link org.objectweb.asm.Opcodes#ASM4}.
|
* must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
|
||||||
*/
|
*/
|
||||||
protected final int api;
|
protected final int api;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.signature.SignatureVisitor}.
|
* Constructs a new {@link SignatureVisitor}.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* the ASM API version implemented by this visitor. Must be one
|
* the ASM API version implemented by this visitor. Must be one
|
||||||
* of {@link org.objectweb.asm.Opcodes#ASM4}.
|
* of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
|
||||||
*/
|
*/
|
||||||
public SignatureVisitor(final int api) {
|
public SignatureVisitor(final int api) {
|
||||||
|
if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
this.api = api;
|
this.api = api;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,10 +63,10 @@ public class SignatureWriter extends SignatureVisitor {
|
|||||||
private int argumentStack;
|
private int argumentStack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.signature.SignatureWriter} object.
|
* Constructs a new {@link SignatureWriter} object.
|
||||||
*/
|
*/
|
||||||
public SignatureWriter() {
|
public SignatureWriter() {
|
||||||
super(Opcodes.ASM4);
|
super(Opcodes.ASM5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.objectweb.asm.tree;
|
package org.objectweb.asm.tree;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -127,6 +128,28 @@ public abstract class AbstractInsnNode {
|
|||||||
*/
|
*/
|
||||||
protected int opcode;
|
protected int opcode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runtime visible type annotations of this instruction. This field is
|
||||||
|
* only used for real instructions (i.e. not for labels, frames, or line
|
||||||
|
* number nodes). This list is a list of {@link TypeAnnotationNode} objects.
|
||||||
|
* May be <tt>null</tt>.
|
||||||
|
*
|
||||||
|
* @associates org.objectweb.asm.tree.TypeAnnotationNode
|
||||||
|
* @label visible
|
||||||
|
*/
|
||||||
|
public List<TypeAnnotationNode> visibleTypeAnnotations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runtime invisible type annotations of this instruction. This field is
|
||||||
|
* only used for real instructions (i.e. not for labels, frames, or line
|
||||||
|
* number nodes). This list is a list of {@link TypeAnnotationNode} objects.
|
||||||
|
* May be <tt>null</tt>.
|
||||||
|
*
|
||||||
|
* @associates org.objectweb.asm.tree.TypeAnnotationNode
|
||||||
|
* @label invisible
|
||||||
|
*/
|
||||||
|
public List<TypeAnnotationNode> invisibleTypeAnnotations;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Previous instruction in the list to which this instruction belongs.
|
* Previous instruction in the list to which this instruction belongs.
|
||||||
*/
|
*/
|
||||||
@@ -146,7 +169,7 @@ public abstract class AbstractInsnNode {
|
|||||||
int index;
|
int index;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.AbstractInsnNode}.
|
* Constructs a new {@link AbstractInsnNode}.
|
||||||
*
|
*
|
||||||
* @param opcode
|
* @param opcode
|
||||||
* the opcode of the instruction to be constructed.
|
* the opcode of the instruction to be constructed.
|
||||||
@@ -203,6 +226,29 @@ public abstract class AbstractInsnNode {
|
|||||||
*/
|
*/
|
||||||
public abstract void accept(final MethodVisitor cv);
|
public abstract void accept(final MethodVisitor cv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the given visitor visit the annotations of this instruction.
|
||||||
|
*
|
||||||
|
* @param mv
|
||||||
|
* a method visitor.
|
||||||
|
*/
|
||||||
|
protected final void acceptAnnotations(final MethodVisitor mv) {
|
||||||
|
int n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations
|
||||||
|
.size();
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
TypeAnnotationNode an = visibleTypeAnnotations.get(i);
|
||||||
|
an.accept(mv.visitInsnAnnotation(an.typeRef, an.typePath, an.desc,
|
||||||
|
true));
|
||||||
|
}
|
||||||
|
n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
|
||||||
|
.size();
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
|
||||||
|
an.accept(mv.visitInsnAnnotation(an.typeRef, an.typePath, an.desc,
|
||||||
|
false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a copy of this instruction.
|
* Returns a copy of this instruction.
|
||||||
*
|
*
|
||||||
@@ -245,4 +291,36 @@ public abstract class AbstractInsnNode {
|
|||||||
}
|
}
|
||||||
return clones;
|
return clones;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clones the annotations of the given instruction into this instruction.
|
||||||
|
*
|
||||||
|
* @param insn
|
||||||
|
* the source instruction.
|
||||||
|
* @return this instruction.
|
||||||
|
*/
|
||||||
|
protected final AbstractInsnNode cloneAnnotations(
|
||||||
|
final AbstractInsnNode insn) {
|
||||||
|
if (insn.visibleTypeAnnotations != null) {
|
||||||
|
this.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>();
|
||||||
|
for (int i = 0; i < insn.visibleTypeAnnotations.size(); ++i) {
|
||||||
|
TypeAnnotationNode src = insn.visibleTypeAnnotations.get(i);
|
||||||
|
TypeAnnotationNode ann = new TypeAnnotationNode(src.typeRef,
|
||||||
|
src.typePath, src.desc);
|
||||||
|
src.accept(ann);
|
||||||
|
this.visibleTypeAnnotations.add(ann);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (insn.invisibleTypeAnnotations != null) {
|
||||||
|
this.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>();
|
||||||
|
for (int i = 0; i < insn.invisibleTypeAnnotations.size(); ++i) {
|
||||||
|
TypeAnnotationNode src = insn.invisibleTypeAnnotations.get(i);
|
||||||
|
TypeAnnotationNode ann = new TypeAnnotationNode(src.typeRef,
|
||||||
|
src.typePath, src.desc);
|
||||||
|
src.accept(ann);
|
||||||
|
this.invisibleTypeAnnotations.add(ann);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,14 +54,14 @@ public class AnnotationNode extends AnnotationVisitor {
|
|||||||
* {@link Short}, {@link Integer}, {@link Long}, {@link Float},
|
* {@link Short}, {@link Integer}, {@link Long}, {@link Float},
|
||||||
* {@link Double}, {@link String} or {@link org.objectweb.asm.Type}, or an
|
* {@link Double}, {@link String} or {@link org.objectweb.asm.Type}, or an
|
||||||
* two elements String array (for enumeration values), a
|
* two elements String array (for enumeration values), a
|
||||||
* {@link org.objectweb.asm.tree.AnnotationNode}, or a {@link java.util.List} of values of one of the
|
* {@link AnnotationNode}, or a {@link List} of values of one of the
|
||||||
* preceding types. The list may be <tt>null</tt> if there is no name value
|
* preceding types. The list may be <tt>null</tt> if there is no name value
|
||||||
* pair.
|
* pair.
|
||||||
*/
|
*/
|
||||||
public List<Object> values;
|
public List<Object> values;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.AnnotationNode}. <i>Subclasses must not use this
|
* Constructs a new {@link AnnotationNode}. <i>Subclasses must not use this
|
||||||
* constructor</i>. Instead, they must use the
|
* constructor</i>. Instead, they must use the
|
||||||
* {@link #AnnotationNode(int, String)} version.
|
* {@link #AnnotationNode(int, String)} version.
|
||||||
*
|
*
|
||||||
@@ -69,15 +69,15 @@ public class AnnotationNode extends AnnotationVisitor {
|
|||||||
* the class descriptor of the annotation class.
|
* the class descriptor of the annotation class.
|
||||||
*/
|
*/
|
||||||
public AnnotationNode(final String desc) {
|
public AnnotationNode(final String desc) {
|
||||||
this(Opcodes.ASM4, desc);
|
this(Opcodes.ASM5, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.AnnotationNode}.
|
* Constructs a new {@link AnnotationNode}.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* the ASM API version implemented by this visitor. Must be one
|
* the ASM API version implemented by this visitor. Must be one
|
||||||
* of {@link org.objectweb.asm.Opcodes#ASM4}.
|
* of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
|
||||||
* @param desc
|
* @param desc
|
||||||
* the class descriptor of the annotation class.
|
* the class descriptor of the annotation class.
|
||||||
*/
|
*/
|
||||||
@@ -87,13 +87,13 @@ public class AnnotationNode extends AnnotationVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.AnnotationNode} to visit an array value.
|
* Constructs a new {@link AnnotationNode} to visit an array value.
|
||||||
*
|
*
|
||||||
* @param values
|
* @param values
|
||||||
* where the visited values must be stored.
|
* where the visited values must be stored.
|
||||||
*/
|
*/
|
||||||
AnnotationNode(final List<Object> values) {
|
AnnotationNode(final List<Object> values) {
|
||||||
super(Opcodes.ASM4);
|
super(Opcodes.ASM5);
|
||||||
this.values = values;
|
this.values = values;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +166,8 @@ public class AnnotationNode extends AnnotationVisitor {
|
|||||||
* versions of the ASM API than the given version.
|
* versions of the ASM API than the given version.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* an ASM API version. Must be one of {@link org.objectweb.asm.Opcodes#ASM4}.
|
* an ASM API version. Must be one of {@link Opcodes#ASM4} or
|
||||||
|
* {@link Opcodes#ASM5}.
|
||||||
*/
|
*/
|
||||||
public void check(final int api) {
|
public void check(final int api) {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import org.objectweb.asm.ClassVisitor;
|
|||||||
import org.objectweb.asm.FieldVisitor;
|
import org.objectweb.asm.FieldVisitor;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import org.objectweb.asm.TypePath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A node that represents a class.
|
* A node that represents a class.
|
||||||
@@ -116,7 +117,7 @@ public class ClassNode extends ClassVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The runtime visible annotations of this class. This list is a list of
|
* The runtime visible annotations of this class. This list is a list of
|
||||||
* {@link org.objectweb.asm.tree.AnnotationNode} objects. May be <tt>null</tt>.
|
* {@link AnnotationNode} objects. May be <tt>null</tt>.
|
||||||
*
|
*
|
||||||
* @associates org.objectweb.asm.tree.AnnotationNode
|
* @associates org.objectweb.asm.tree.AnnotationNode
|
||||||
* @label visible
|
* @label visible
|
||||||
@@ -125,16 +126,34 @@ public class ClassNode extends ClassVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The runtime invisible annotations of this class. This list is a list of
|
* The runtime invisible annotations of this class. This list is a list of
|
||||||
* {@link org.objectweb.asm.tree.AnnotationNode} objects. May be <tt>null</tt>.
|
* {@link AnnotationNode} objects. May be <tt>null</tt>.
|
||||||
*
|
*
|
||||||
* @associates org.objectweb.asm.tree.AnnotationNode
|
* @associates org.objectweb.asm.tree.AnnotationNode
|
||||||
* @label invisible
|
* @label invisible
|
||||||
*/
|
*/
|
||||||
public List<AnnotationNode> invisibleAnnotations;
|
public List<AnnotationNode> invisibleAnnotations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runtime visible type annotations of this class. This list is a list
|
||||||
|
* of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
|
||||||
|
*
|
||||||
|
* @associates org.objectweb.asm.tree.TypeAnnotationNode
|
||||||
|
* @label visible
|
||||||
|
*/
|
||||||
|
public List<TypeAnnotationNode> visibleTypeAnnotations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runtime invisible type annotations of this class. This list is a list
|
||||||
|
* of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
|
||||||
|
*
|
||||||
|
* @associates org.objectweb.asm.tree.TypeAnnotationNode
|
||||||
|
* @label invisible
|
||||||
|
*/
|
||||||
|
public List<TypeAnnotationNode> invisibleTypeAnnotations;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The non standard attributes of this class. This list is a list of
|
* The non standard attributes of this class. This list is a list of
|
||||||
* {@link org.objectweb.asm.Attribute} objects. May be <tt>null</tt>.
|
* {@link Attribute} objects. May be <tt>null</tt>.
|
||||||
*
|
*
|
||||||
* @associates org.objectweb.asm.Attribute
|
* @associates org.objectweb.asm.Attribute
|
||||||
*/
|
*/
|
||||||
@@ -165,20 +184,20 @@ public class ClassNode extends ClassVisitor {
|
|||||||
public List<MethodNode> methods;
|
public List<MethodNode> methods;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.ClassNode}. <i>Subclasses must not use this
|
* Constructs a new {@link ClassNode}. <i>Subclasses must not use this
|
||||||
* constructor</i>. Instead, they must use the {@link #ClassNode(int)}
|
* constructor</i>. Instead, they must use the {@link #ClassNode(int)}
|
||||||
* version.
|
* version.
|
||||||
*/
|
*/
|
||||||
public ClassNode() {
|
public ClassNode() {
|
||||||
this(Opcodes.ASM4);
|
this(Opcodes.ASM5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.ClassNode}.
|
* Constructs a new {@link ClassNode}.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* the ASM API version implemented by this visitor. Must be one
|
* the ASM API version implemented by this visitor. Must be one
|
||||||
* of {@link org.objectweb.asm.Opcodes#ASM4}.
|
* of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
|
||||||
*/
|
*/
|
||||||
public ClassNode(final int api) {
|
public ClassNode(final int api) {
|
||||||
super(api);
|
super(api);
|
||||||
@@ -238,6 +257,24 @@ public class ClassNode extends ClassVisitor {
|
|||||||
return an;
|
return an;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AnnotationVisitor visitTypeAnnotation(int typeRef,
|
||||||
|
TypePath typePath, String desc, boolean visible) {
|
||||||
|
TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
|
||||||
|
if (visible) {
|
||||||
|
if (visibleTypeAnnotations == null) {
|
||||||
|
visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
|
||||||
|
}
|
||||||
|
visibleTypeAnnotations.add(an);
|
||||||
|
} else {
|
||||||
|
if (invisibleTypeAnnotations == null) {
|
||||||
|
invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
|
||||||
|
}
|
||||||
|
invisibleTypeAnnotations.add(an);
|
||||||
|
}
|
||||||
|
return an;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitAttribute(final Attribute attr) {
|
public void visitAttribute(final Attribute attr) {
|
||||||
if (attrs == null) {
|
if (attrs == null) {
|
||||||
@@ -286,10 +323,26 @@ public class ClassNode extends ClassVisitor {
|
|||||||
* API than the given version.
|
* API than the given version.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* an ASM API version. Must be one of {@link org.objectweb.asm.Opcodes#ASM4}.
|
* an ASM API version. Must be one of {@link Opcodes#ASM4} or
|
||||||
|
* {@link Opcodes#ASM5}.
|
||||||
*/
|
*/
|
||||||
public void check(final int api) {
|
public void check(final int api) {
|
||||||
// nothing to do
|
if (api == Opcodes.ASM4) {
|
||||||
|
if (visibleTypeAnnotations != null
|
||||||
|
&& visibleTypeAnnotations.size() > 0) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
if (invisibleTypeAnnotations != null
|
||||||
|
&& invisibleTypeAnnotations.size() > 0) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
for (FieldNode f : fields) {
|
||||||
|
f.check(api);
|
||||||
|
}
|
||||||
|
for (MethodNode m : methods) {
|
||||||
|
m.check(api);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -323,6 +376,19 @@ public class ClassNode extends ClassVisitor {
|
|||||||
AnnotationNode an = invisibleAnnotations.get(i);
|
AnnotationNode an = invisibleAnnotations.get(i);
|
||||||
an.accept(cv.visitAnnotation(an.desc, false));
|
an.accept(cv.visitAnnotation(an.desc, false));
|
||||||
}
|
}
|
||||||
|
n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
TypeAnnotationNode an = visibleTypeAnnotations.get(i);
|
||||||
|
an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
|
||||||
|
true));
|
||||||
|
}
|
||||||
|
n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
|
||||||
|
.size();
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
|
||||||
|
an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
|
||||||
|
false));
|
||||||
|
}
|
||||||
n = attrs == null ? 0 : attrs.size();
|
n = attrs == null ? 0 : attrs.size();
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
cv.visitAttribute(attrs.get(i));
|
cv.visitAttribute(attrs.get(i));
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class FieldInsnNode extends AbstractInsnNode {
|
|||||||
public String desc;
|
public String desc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.FieldInsnNode}.
|
* Constructs a new {@link FieldInsnNode}.
|
||||||
*
|
*
|
||||||
* @param opcode
|
* @param opcode
|
||||||
* the opcode of the type instruction to be constructed. This
|
* the opcode of the type instruction to be constructed. This
|
||||||
@@ -97,12 +97,14 @@ public class FieldInsnNode extends AbstractInsnNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(final MethodVisitor cv) {
|
public void accept(final MethodVisitor mv) {
|
||||||
cv.visitFieldInsn(opcode, owner, name, desc);
|
mv.visitFieldInsn(opcode, owner, name, desc);
|
||||||
|
acceptAnnotations(mv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
||||||
return new FieldInsnNode(opcode, owner, name, desc);
|
return new FieldInsnNode(opcode, owner, name, desc)
|
||||||
|
.cloneAnnotations(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import org.objectweb.asm.Attribute;
|
|||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.FieldVisitor;
|
import org.objectweb.asm.FieldVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import org.objectweb.asm.TypePath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A node that represents a field.
|
* A node that represents a field.
|
||||||
@@ -75,7 +76,7 @@ public class FieldNode extends FieldVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The runtime visible annotations of this field. This list is a list of
|
* The runtime visible annotations of this field. This list is a list of
|
||||||
* {@link org.objectweb.asm.tree.AnnotationNode} objects. May be <tt>null</tt>.
|
* {@link AnnotationNode} objects. May be <tt>null</tt>.
|
||||||
*
|
*
|
||||||
* @associates org.objectweb.asm.tree.AnnotationNode
|
* @associates org.objectweb.asm.tree.AnnotationNode
|
||||||
* @label visible
|
* @label visible
|
||||||
@@ -84,23 +85,41 @@ public class FieldNode extends FieldVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The runtime invisible annotations of this field. This list is a list of
|
* The runtime invisible annotations of this field. This list is a list of
|
||||||
* {@link org.objectweb.asm.tree.AnnotationNode} objects. May be <tt>null</tt>.
|
* {@link AnnotationNode} objects. May be <tt>null</tt>.
|
||||||
*
|
*
|
||||||
* @associates org.objectweb.asm.tree.AnnotationNode
|
* @associates org.objectweb.asm.tree.AnnotationNode
|
||||||
* @label invisible
|
* @label invisible
|
||||||
*/
|
*/
|
||||||
public List<AnnotationNode> invisibleAnnotations;
|
public List<AnnotationNode> invisibleAnnotations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runtime visible type annotations of this field. This list is a list
|
||||||
|
* of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
|
||||||
|
*
|
||||||
|
* @associates org.objectweb.asm.tree.TypeAnnotationNode
|
||||||
|
* @label visible
|
||||||
|
*/
|
||||||
|
public List<TypeAnnotationNode> visibleTypeAnnotations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runtime invisible type annotations of this field. This list is a list
|
||||||
|
* of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
|
||||||
|
*
|
||||||
|
* @associates org.objectweb.asm.tree.TypeAnnotationNode
|
||||||
|
* @label invisible
|
||||||
|
*/
|
||||||
|
public List<TypeAnnotationNode> invisibleTypeAnnotations;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The non standard attributes of this field. This list is a list of
|
* The non standard attributes of this field. This list is a list of
|
||||||
* {@link org.objectweb.asm.Attribute} objects. May be <tt>null</tt>.
|
* {@link Attribute} objects. May be <tt>null</tt>.
|
||||||
*
|
*
|
||||||
* @associates org.objectweb.asm.Attribute
|
* @associates org.objectweb.asm.Attribute
|
||||||
*/
|
*/
|
||||||
public List<Attribute> attrs;
|
public List<Attribute> attrs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.FieldNode}. <i>Subclasses must not use this
|
* Constructs a new {@link FieldNode}. <i>Subclasses must not use this
|
||||||
* constructor</i>. Instead, they must use the
|
* constructor</i>. Instead, they must use the
|
||||||
* {@link #FieldNode(int, int, String, String, String, Object)} version.
|
* {@link #FieldNode(int, int, String, String, String, Object)} version.
|
||||||
*
|
*
|
||||||
@@ -123,17 +142,17 @@ public class FieldNode extends FieldVisitor {
|
|||||||
*/
|
*/
|
||||||
public FieldNode(final int access, final String name, final String desc,
|
public FieldNode(final int access, final String name, final String desc,
|
||||||
final String signature, final Object value) {
|
final String signature, final Object value) {
|
||||||
this(Opcodes.ASM4, access, name, desc, signature, value);
|
this(Opcodes.ASM5, access, name, desc, signature, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.FieldNode}. <i>Subclasses must not use this
|
* Constructs a new {@link FieldNode}. <i>Subclasses must not use this
|
||||||
* constructor</i>. Instead, they must use the
|
* constructor</i>. Instead, they must use the
|
||||||
* {@link #FieldNode(int, int, String, String, String, Object)} version.
|
* {@link #FieldNode(int, int, String, String, String, Object)} version.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* the ASM API version implemented by this visitor. Must be one
|
* the ASM API version implemented by this visitor. Must be one
|
||||||
* of {@link org.objectweb.asm.Opcodes#ASM4}.
|
* of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
|
||||||
* @param access
|
* @param access
|
||||||
* the field's access flags (see
|
* the field's access flags (see
|
||||||
* {@link org.objectweb.asm.Opcodes}). This parameter also
|
* {@link org.objectweb.asm.Opcodes}). This parameter also
|
||||||
@@ -183,6 +202,24 @@ public class FieldNode extends FieldVisitor {
|
|||||||
return an;
|
return an;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AnnotationVisitor visitTypeAnnotation(int typeRef,
|
||||||
|
TypePath typePath, String desc, boolean visible) {
|
||||||
|
TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
|
||||||
|
if (visible) {
|
||||||
|
if (visibleTypeAnnotations == null) {
|
||||||
|
visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
|
||||||
|
}
|
||||||
|
visibleTypeAnnotations.add(an);
|
||||||
|
} else {
|
||||||
|
if (invisibleTypeAnnotations == null) {
|
||||||
|
invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
|
||||||
|
}
|
||||||
|
invisibleTypeAnnotations.add(an);
|
||||||
|
}
|
||||||
|
return an;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitAttribute(final Attribute attr) {
|
public void visitAttribute(final Attribute attr) {
|
||||||
if (attrs == null) {
|
if (attrs == null) {
|
||||||
@@ -206,10 +243,20 @@ public class FieldNode extends FieldVisitor {
|
|||||||
* API than the given version.
|
* API than the given version.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* an ASM API version. Must be one of {@link org.objectweb.asm.Opcodes#ASM4}.
|
* an ASM API version. Must be one of {@link Opcodes#ASM4} or
|
||||||
|
* {@link Opcodes#ASM5}.
|
||||||
*/
|
*/
|
||||||
public void check(final int api) {
|
public void check(final int api) {
|
||||||
// nothing to do
|
if (api == Opcodes.ASM4) {
|
||||||
|
if (visibleTypeAnnotations != null
|
||||||
|
&& visibleTypeAnnotations.size() > 0) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
if (invisibleTypeAnnotations != null
|
||||||
|
&& invisibleTypeAnnotations.size() > 0) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -234,6 +281,19 @@ public class FieldNode extends FieldVisitor {
|
|||||||
AnnotationNode an = invisibleAnnotations.get(i);
|
AnnotationNode an = invisibleAnnotations.get(i);
|
||||||
an.accept(fv.visitAnnotation(an.desc, false));
|
an.accept(fv.visitAnnotation(an.desc, false));
|
||||||
}
|
}
|
||||||
|
n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
TypeAnnotationNode an = visibleTypeAnnotations.get(i);
|
||||||
|
an.accept(fv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
|
||||||
|
true));
|
||||||
|
}
|
||||||
|
n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
|
||||||
|
.size();
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
|
||||||
|
an.accept(fv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
|
||||||
|
false));
|
||||||
|
}
|
||||||
n = attrs == null ? 0 : attrs.size();
|
n = attrs == null ? 0 : attrs.size();
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
fv.visitAttribute(attrs.get(i));
|
fv.visitAttribute(attrs.get(i));
|
||||||
|
|||||||
@@ -47,17 +47,17 @@ import org.objectweb.asm.Opcodes;
|
|||||||
* of the operand stack elements <i>just before</i> <b>i</b> is executed. <br>
|
* of the operand stack elements <i>just before</i> <b>i</b> is executed. <br>
|
||||||
* <br>
|
* <br>
|
||||||
* (*) this is mandatory only for classes whose version is greater than or equal
|
* (*) this is mandatory only for classes whose version is greater than or equal
|
||||||
* to {@link org.objectweb.asm.Opcodes#V1_6 V1_6}.
|
* to {@link Opcodes#V1_6 V1_6}.
|
||||||
*
|
*
|
||||||
* @author Eric Bruneton
|
* @author Eric Bruneton
|
||||||
*/
|
*/
|
||||||
public class FrameNode extends AbstractInsnNode {
|
public class FrameNode extends AbstractInsnNode {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of this frame. Must be {@link org.objectweb.asm.Opcodes#F_NEW} for expanded
|
* The type of this frame. Must be {@link Opcodes#F_NEW} for expanded
|
||||||
* frames, or {@link org.objectweb.asm.Opcodes#F_FULL}, {@link org.objectweb.asm.Opcodes#F_APPEND},
|
* frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
|
||||||
* {@link org.objectweb.asm.Opcodes#F_CHOP}, {@link org.objectweb.asm.Opcodes#F_SAME} or
|
* {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
|
||||||
* {@link org.objectweb.asm.Opcodes#F_APPEND}, {@link org.objectweb.asm.Opcodes#F_SAME1} for compressed frames.
|
* {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames.
|
||||||
*/
|
*/
|
||||||
public int type;
|
public int type;
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ public class FrameNode extends AbstractInsnNode {
|
|||||||
* The types of the local variables of this stack map frame. Elements of
|
* The types of the local variables of this stack map frame. Elements of
|
||||||
* this list can be Integer, String or LabelNode objects (for primitive,
|
* this list can be Integer, String or LabelNode objects (for primitive,
|
||||||
* reference and uninitialized types respectively - see
|
* reference and uninitialized types respectively - see
|
||||||
* {@link org.objectweb.asm.MethodVisitor}).
|
* {@link MethodVisitor}).
|
||||||
*/
|
*/
|
||||||
public List<Object> local;
|
public List<Object> local;
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ public class FrameNode extends AbstractInsnNode {
|
|||||||
* The types of the operand stack elements of this stack map frame. Elements
|
* The types of the operand stack elements of this stack map frame. Elements
|
||||||
* of this list can be Integer, String or LabelNode objects (for primitive,
|
* of this list can be Integer, String or LabelNode objects (for primitive,
|
||||||
* reference and uninitialized types respectively - see
|
* reference and uninitialized types respectively - see
|
||||||
* {@link org.objectweb.asm.MethodVisitor}).
|
* {@link MethodVisitor}).
|
||||||
*/
|
*/
|
||||||
public List<Object> stack;
|
public List<Object> stack;
|
||||||
|
|
||||||
@@ -82,28 +82,28 @@ public class FrameNode extends AbstractInsnNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.FrameNode}.
|
* Constructs a new {@link FrameNode}.
|
||||||
*
|
*
|
||||||
* @param type
|
* @param type
|
||||||
* the type of this frame. Must be {@link org.objectweb.asm.Opcodes#F_NEW} for
|
* the type of this frame. Must be {@link Opcodes#F_NEW} for
|
||||||
* expanded frames, or {@link org.objectweb.asm.Opcodes#F_FULL},
|
* expanded frames, or {@link Opcodes#F_FULL},
|
||||||
* {@link org.objectweb.asm.Opcodes#F_APPEND}, {@link org.objectweb.asm.Opcodes#F_CHOP},
|
* {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP},
|
||||||
* {@link org.objectweb.asm.Opcodes#F_SAME} or {@link org.objectweb.asm.Opcodes#F_APPEND},
|
* {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND},
|
||||||
* {@link org.objectweb.asm.Opcodes#F_SAME1} for compressed frames.
|
* {@link Opcodes#F_SAME1} for compressed frames.
|
||||||
* @param nLocal
|
* @param nLocal
|
||||||
* number of local variables of this stack map frame.
|
* number of local variables of this stack map frame.
|
||||||
* @param local
|
* @param local
|
||||||
* the types of the local variables of this stack map frame.
|
* the types of the local variables of this stack map frame.
|
||||||
* Elements of this list can be Integer, String or LabelNode
|
* Elements of this list can be Integer, String or LabelNode
|
||||||
* objects (for primitive, reference and uninitialized types
|
* objects (for primitive, reference and uninitialized types
|
||||||
* respectively - see {@link org.objectweb.asm.MethodVisitor}).
|
* respectively - see {@link MethodVisitor}).
|
||||||
* @param nStack
|
* @param nStack
|
||||||
* number of operand stack elements of this stack map frame.
|
* number of operand stack elements of this stack map frame.
|
||||||
* @param stack
|
* @param stack
|
||||||
* the types of the operand stack elements of this stack map
|
* the types of the operand stack elements of this stack map
|
||||||
* frame. Elements of this list can be Integer, String or
|
* frame. Elements of this list can be Integer, String or
|
||||||
* LabelNode objects (for primitive, reference and uninitialized
|
* LabelNode objects (for primitive, reference and uninitialized
|
||||||
* types respectively - see {@link org.objectweb.asm.MethodVisitor}).
|
* types respectively - see {@link MethodVisitor}).
|
||||||
*/
|
*/
|
||||||
public FrameNode(final int type, final int nLocal, final Object[] local,
|
public FrameNode(final int type, final int nLocal, final Object[] local,
|
||||||
final int nStack, final Object[] stack) {
|
final int nStack, final Object[] stack) {
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class IincInsnNode extends AbstractInsnNode {
|
|||||||
public int incr;
|
public int incr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.IincInsnNode}.
|
* Constructs a new {@link IincInsnNode}.
|
||||||
*
|
*
|
||||||
* @param var
|
* @param var
|
||||||
* index of the local variable to be incremented.
|
* index of the local variable to be incremented.
|
||||||
@@ -73,10 +73,11 @@ public class IincInsnNode extends AbstractInsnNode {
|
|||||||
@Override
|
@Override
|
||||||
public void accept(final MethodVisitor mv) {
|
public void accept(final MethodVisitor mv) {
|
||||||
mv.visitIincInsn(var, incr);
|
mv.visitIincInsn(var, incr);
|
||||||
|
acceptAnnotations(mv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
||||||
return new IincInsnNode(var, incr);
|
return new IincInsnNode(var, incr).cloneAnnotations(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ public class InnerClassNode {
|
|||||||
public int access;
|
public int access;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.InnerClassNode}.
|
* Constructs a new {@link InnerClassNode}.
|
||||||
*
|
*
|
||||||
* @param name
|
* @param name
|
||||||
* the internal name of an inner class (see
|
* the internal name of an inner class (see
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import java.util.NoSuchElementException;
|
|||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A doubly linked list of {@link org.objectweb.asm.tree.AbstractInsnNode} objects. <i>This
|
* A doubly linked list of {@link AbstractInsnNode} objects. <i>This
|
||||||
* implementation is not thread safe</i>.
|
* implementation is not thread safe</i>.
|
||||||
*/
|
*/
|
||||||
public class InsnList {
|
public class InsnList {
|
||||||
@@ -100,7 +100,7 @@ public class InsnList {
|
|||||||
* the index of the instruction that must be returned.
|
* the index of the instruction that must be returned.
|
||||||
* @return the instruction whose index is given.
|
* @return the instruction whose index is given.
|
||||||
* @throws IndexOutOfBoundsException
|
* @throws IndexOutOfBoundsException
|
||||||
* if (index < 0 || index >= size()).
|
* if (index < 0 || index >= size()).
|
||||||
*/
|
*/
|
||||||
public AbstractInsnNode get(final int index) {
|
public AbstractInsnNode get(final int index) {
|
||||||
if (index < 0 || index >= size) {
|
if (index < 0 || index >= size) {
|
||||||
@@ -207,7 +207,7 @@ public class InsnList {
|
|||||||
* an instruction <i>of this list</i>.
|
* an instruction <i>of this list</i>.
|
||||||
* @param insn
|
* @param insn
|
||||||
* another instruction, <i>which must not belong to any
|
* another instruction, <i>which must not belong to any
|
||||||
* {@link org.objectweb.asm.tree.InsnList}</i>.
|
* {@link InsnList}</i>.
|
||||||
*/
|
*/
|
||||||
public void set(final AbstractInsnNode location, final AbstractInsnNode insn) {
|
public void set(final AbstractInsnNode location, final AbstractInsnNode insn) {
|
||||||
AbstractInsnNode next = location.next;
|
AbstractInsnNode next = location.next;
|
||||||
@@ -241,7 +241,7 @@ public class InsnList {
|
|||||||
*
|
*
|
||||||
* @param insn
|
* @param insn
|
||||||
* an instruction, <i>which must not belong to any
|
* an instruction, <i>which must not belong to any
|
||||||
* {@link org.objectweb.asm.tree.InsnList}</i>.
|
* {@link InsnList}</i>.
|
||||||
*/
|
*/
|
||||||
public void add(final AbstractInsnNode insn) {
|
public void add(final AbstractInsnNode insn) {
|
||||||
++size;
|
++size;
|
||||||
@@ -287,7 +287,7 @@ public class InsnList {
|
|||||||
*
|
*
|
||||||
* @param insn
|
* @param insn
|
||||||
* an instruction, <i>which must not belong to any
|
* an instruction, <i>which must not belong to any
|
||||||
* {@link org.objectweb.asm.tree.InsnList}</i>.
|
* {@link InsnList}</i>.
|
||||||
*/
|
*/
|
||||||
public void insert(final AbstractInsnNode insn) {
|
public void insert(final AbstractInsnNode insn) {
|
||||||
++size;
|
++size;
|
||||||
@@ -336,7 +336,7 @@ public class InsnList {
|
|||||||
* inserted.
|
* inserted.
|
||||||
* @param insn
|
* @param insn
|
||||||
* the instruction to be inserted, <i>which must not belong to
|
* the instruction to be inserted, <i>which must not belong to
|
||||||
* any {@link org.objectweb.asm.tree.InsnList}</i>.
|
* any {@link InsnList}</i>.
|
||||||
*/
|
*/
|
||||||
public void insert(final AbstractInsnNode location,
|
public void insert(final AbstractInsnNode location,
|
||||||
final AbstractInsnNode insn) {
|
final AbstractInsnNode insn) {
|
||||||
@@ -392,7 +392,7 @@ public class InsnList {
|
|||||||
* inserted.
|
* inserted.
|
||||||
* @param insn
|
* @param insn
|
||||||
* the instruction to be inserted, <i>which must not belong to
|
* the instruction to be inserted, <i>which must not belong to
|
||||||
* any {@link org.objectweb.asm.tree.InsnList}</i>.
|
* any {@link InsnList}</i>.
|
||||||
*/
|
*/
|
||||||
public void insertBefore(final AbstractInsnNode location,
|
public void insertBefore(final AbstractInsnNode location,
|
||||||
final AbstractInsnNode insn) {
|
final AbstractInsnNode insn) {
|
||||||
@@ -479,7 +479,7 @@ public class InsnList {
|
|||||||
*
|
*
|
||||||
* @param mark
|
* @param mark
|
||||||
* if the instructions must be marked as no longer belonging to
|
* if the instructions must be marked as no longer belonging to
|
||||||
* any {@link org.objectweb.asm.tree.InsnList}.
|
* any {@link InsnList}.
|
||||||
*/
|
*/
|
||||||
void removeAll(final boolean mark) {
|
void removeAll(final boolean mark) {
|
||||||
if (mark) {
|
if (mark) {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import org.objectweb.asm.MethodVisitor;
|
|||||||
public class InsnNode extends AbstractInsnNode {
|
public class InsnNode extends AbstractInsnNode {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.InsnNode}.
|
* Constructs a new {@link InsnNode}.
|
||||||
*
|
*
|
||||||
* @param opcode
|
* @param opcode
|
||||||
* the opcode of the instruction to be constructed. This opcode
|
* the opcode of the instruction to be constructed. This opcode
|
||||||
@@ -78,10 +78,11 @@ public class InsnNode extends AbstractInsnNode {
|
|||||||
@Override
|
@Override
|
||||||
public void accept(final MethodVisitor mv) {
|
public void accept(final MethodVisitor mv) {
|
||||||
mv.visitInsn(opcode);
|
mv.visitInsn(opcode);
|
||||||
|
acceptAnnotations(mv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
||||||
return new InsnNode(opcode);
|
return new InsnNode(opcode).cloneAnnotations(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class IntInsnNode extends AbstractInsnNode {
|
|||||||
public int operand;
|
public int operand;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.IntInsnNode}.
|
* Constructs a new {@link IntInsnNode}.
|
||||||
*
|
*
|
||||||
* @param opcode
|
* @param opcode
|
||||||
* the opcode of the instruction to be constructed. This opcode
|
* the opcode of the instruction to be constructed. This opcode
|
||||||
@@ -78,10 +78,11 @@ public class IntInsnNode extends AbstractInsnNode {
|
|||||||
@Override
|
@Override
|
||||||
public void accept(final MethodVisitor mv) {
|
public void accept(final MethodVisitor mv) {
|
||||||
mv.visitIntInsn(opcode, operand);
|
mv.visitIntInsn(opcode, operand);
|
||||||
|
acceptAnnotations(mv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
||||||
return new IntInsnNode(opcode, operand);
|
return new IntInsnNode(opcode, operand).cloneAnnotations(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class InvokeDynamicInsnNode extends AbstractInsnNode {
|
|||||||
public Object[] bsmArgs;
|
public Object[] bsmArgs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.InvokeDynamicInsnNode}.
|
* Constructs a new {@link InvokeDynamicInsnNode}.
|
||||||
*
|
*
|
||||||
* @param name
|
* @param name
|
||||||
* invokedynamic name.
|
* invokedynamic name.
|
||||||
@@ -91,10 +91,12 @@ public class InvokeDynamicInsnNode extends AbstractInsnNode {
|
|||||||
@Override
|
@Override
|
||||||
public void accept(final MethodVisitor mv) {
|
public void accept(final MethodVisitor mv) {
|
||||||
mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
|
mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
|
||||||
|
acceptAnnotations(mv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
||||||
return new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs);
|
return new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs)
|
||||||
|
.cloneAnnotations(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ public class JumpInsnNode extends AbstractInsnNode {
|
|||||||
public LabelNode label;
|
public LabelNode label;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.JumpInsnNode}.
|
* Constructs a new {@link JumpInsnNode}.
|
||||||
*
|
*
|
||||||
* @param opcode
|
* @param opcode
|
||||||
* the opcode of the type instruction to be constructed. This
|
* the opcode of the type instruction to be constructed. This
|
||||||
@@ -86,10 +86,12 @@ public class JumpInsnNode extends AbstractInsnNode {
|
|||||||
@Override
|
@Override
|
||||||
public void accept(final MethodVisitor mv) {
|
public void accept(final MethodVisitor mv) {
|
||||||
mv.visitJumpInsn(opcode, label.getLabel());
|
mv.visitJumpInsn(opcode, label.getLabel());
|
||||||
|
acceptAnnotations(mv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
||||||
return new JumpInsnNode(opcode, clone(label, labels));
|
return new JumpInsnNode(opcode, clone(label, labels))
|
||||||
|
.cloneAnnotations(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import org.objectweb.asm.Label;
|
|||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link org.objectweb.asm.tree.AbstractInsnNode} that encapsulates a {@link org.objectweb.asm.Label}.
|
* An {@link AbstractInsnNode} that encapsulates a {@link Label}.
|
||||||
*/
|
*/
|
||||||
public class LabelNode extends AbstractInsnNode {
|
public class LabelNode extends AbstractInsnNode {
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public class LdcInsnNode extends AbstractInsnNode {
|
|||||||
public Object cst;
|
public Object cst;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.LdcInsnNode}.
|
* Constructs a new {@link LdcInsnNode}.
|
||||||
*
|
*
|
||||||
* @param cst
|
* @param cst
|
||||||
* the constant to be loaded on the stack. This parameter must be
|
* the constant to be loaded on the stack. This parameter must be
|
||||||
@@ -69,10 +69,11 @@ public class LdcInsnNode extends AbstractInsnNode {
|
|||||||
@Override
|
@Override
|
||||||
public void accept(final MethodVisitor mv) {
|
public void accept(final MethodVisitor mv) {
|
||||||
mv.visitLdcInsn(cst);
|
mv.visitLdcInsn(cst);
|
||||||
|
acceptAnnotations(mv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
||||||
return new LdcInsnNode(cst);
|
return new LdcInsnNode(cst).cloneAnnotations(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ public class LineNumberNode extends AbstractInsnNode {
|
|||||||
public LabelNode start;
|
public LabelNode start;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.LineNumberNode}.
|
* Constructs a new {@link LineNumberNode}.
|
||||||
*
|
*
|
||||||
* @param line
|
* @param line
|
||||||
* a line number. This number refers to the source file from
|
* a line number. This number refers to the source file from
|
||||||
|
|||||||
@@ -0,0 +1,157 @@
|
|||||||
|
/***
|
||||||
|
* ASM: a very small and fast Java bytecode manipulation framework
|
||||||
|
* Copyright (c) 2000-2011 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.tree;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.objectweb.asm.Label;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import org.objectweb.asm.TypePath;
|
||||||
|
import org.objectweb.asm.TypeReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A node that represents a type annotation on a local or resource variable.
|
||||||
|
*
|
||||||
|
* @author Eric Bruneton
|
||||||
|
*/
|
||||||
|
public class LocalVariableAnnotationNode extends TypeAnnotationNode {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fist instructions corresponding to the continuous ranges that make
|
||||||
|
* the scope of this local variable (inclusive). Must not be <tt>null</tt>.
|
||||||
|
*/
|
||||||
|
public List<LabelNode> start;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last instructions corresponding to the continuous ranges that make
|
||||||
|
* the scope of this local variable (exclusive). This list must have the
|
||||||
|
* same size as the 'start' list. Must not be <tt>null</tt>.
|
||||||
|
*/
|
||||||
|
public List<LabelNode> end;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The local variable's index in each range. This list must have the same
|
||||||
|
* size as the 'start' list. Must not be <tt>null</tt>.
|
||||||
|
*/
|
||||||
|
public List<Integer> index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link LocalVariableAnnotationNode}. <i>Subclasses must
|
||||||
|
* not use this constructor</i>. Instead, they must use the
|
||||||
|
* {@link #LocalVariableAnnotationNode(int, TypePath, LabelNode[], LabelNode[], int[], String)}
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
* @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
|
||||||
|
* <tt>null</tt> 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.
|
||||||
|
*/
|
||||||
|
public LocalVariableAnnotationNode(int typeRef, TypePath typePath,
|
||||||
|
LabelNode[] start, LabelNode[] end, int[] index, String desc) {
|
||||||
|
this(Opcodes.ASM5, typeRef, typePath, start, end, index, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link LocalVariableAnnotationNode}.
|
||||||
|
*
|
||||||
|
* @param api
|
||||||
|
* the ASM API version implemented by this visitor. Must be one
|
||||||
|
* of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
|
||||||
|
* @param typeRef
|
||||||
|
* a reference to the annotated type. See {@link TypeReference}.
|
||||||
|
* @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 typePath
|
||||||
|
* the path to the annotated type argument, wildcard bound, array
|
||||||
|
* element type, or static inner type within 'typeRef'. May be
|
||||||
|
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||||
|
* @param desc
|
||||||
|
* the class descriptor of the annotation class.
|
||||||
|
*/
|
||||||
|
public LocalVariableAnnotationNode(int api, int typeRef, TypePath typePath,
|
||||||
|
LabelNode[] start, LabelNode[] end, int[] index, String desc) {
|
||||||
|
super(api, typeRef, typePath, desc);
|
||||||
|
this.start = new ArrayList<LabelNode>(start.length);
|
||||||
|
this.start.addAll(Arrays.asList(start));
|
||||||
|
this.end = new ArrayList<LabelNode>(end.length);
|
||||||
|
this.end.addAll(Arrays.asList(end));
|
||||||
|
this.index = new ArrayList<Integer>(index.length);
|
||||||
|
for (int i : index) {
|
||||||
|
this.index.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the given visitor visit this type annotation.
|
||||||
|
*
|
||||||
|
* @param mv
|
||||||
|
* the visitor that must visit this annotation.
|
||||||
|
* @param visible
|
||||||
|
* <tt>true</tt> if the annotation is visible at runtime.
|
||||||
|
*/
|
||||||
|
public void accept(final MethodVisitor mv, boolean visible) {
|
||||||
|
Label[] start = new Label[this.start.size()];
|
||||||
|
Label[] end = new Label[this.end.size()];
|
||||||
|
int[] index = new int[this.index.size()];
|
||||||
|
for (int i = 0; i < start.length; ++i) {
|
||||||
|
start[i] = this.start.get(i).getLabel();
|
||||||
|
end[i] = this.end.get(i).getLabel();
|
||||||
|
index[i] = this.index.get(i);
|
||||||
|
}
|
||||||
|
accept(mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
|
||||||
|
index, desc, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -71,7 +71,7 @@ public class LocalVariableNode {
|
|||||||
public int index;
|
public int index;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.LocalVariableNode}.
|
* Constructs a new {@link LocalVariableNode}.
|
||||||
*
|
*
|
||||||
* @param name
|
* @param name
|
||||||
* the name of a local variable.
|
* the name of a local variable.
|
||||||
|
|||||||
@@ -57,12 +57,12 @@ public class LookupSwitchInsnNode extends AbstractInsnNode {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Beginnings of the handler blocks. This list is a list of
|
* Beginnings of the handler blocks. This list is a list of
|
||||||
* {@link org.objectweb.asm.tree.LabelNode} objects.
|
* {@link LabelNode} objects.
|
||||||
*/
|
*/
|
||||||
public List<LabelNode> labels;
|
public List<LabelNode> labels;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.LookupSwitchInsnNode}.
|
* Constructs a new {@link LookupSwitchInsnNode}.
|
||||||
*
|
*
|
||||||
* @param dflt
|
* @param dflt
|
||||||
* beginning of the default handler block.
|
* beginning of the default handler block.
|
||||||
@@ -105,6 +105,7 @@ public class LookupSwitchInsnNode extends AbstractInsnNode {
|
|||||||
labels[i] = this.labels.get(i).getLabel();
|
labels[i] = this.labels.get(i).getLabel();
|
||||||
}
|
}
|
||||||
mv.visitLookupSwitchInsn(dflt.getLabel(), keys, labels);
|
mv.visitLookupSwitchInsn(dflt.getLabel(), keys, labels);
|
||||||
|
acceptAnnotations(mv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -112,6 +113,6 @@ public class LookupSwitchInsnNode extends AbstractInsnNode {
|
|||||||
LookupSwitchInsnNode clone = new LookupSwitchInsnNode(clone(dflt,
|
LookupSwitchInsnNode clone = new LookupSwitchInsnNode(clone(dflt,
|
||||||
labels), null, clone(this.labels, labels));
|
labels), null, clone(this.labels, labels));
|
||||||
clone.keys.addAll(keys);
|
clone.keys.addAll(keys);
|
||||||
return clone;
|
return clone.cloneAnnotations(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class MethodInsnNode extends AbstractInsnNode {
|
|||||||
public String desc;
|
public String desc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.MethodInsnNode}.
|
* Constructs a new {@link MethodInsnNode}.
|
||||||
*
|
*
|
||||||
* @param opcode
|
* @param opcode
|
||||||
* the opcode of the type instruction to be constructed. This
|
* the opcode of the type instruction to be constructed. This
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import org.objectweb.asm.Label;
|
|||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
import org.objectweb.asm.TypePath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A node that represents a method.
|
* A node that represents a method.
|
||||||
@@ -50,7 +51,7 @@ import org.objectweb.asm.Type;
|
|||||||
public class MethodNode extends MethodVisitor {
|
public class MethodNode extends MethodVisitor {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The method's access flags (see {@link org.objectweb.asm.Opcodes}). This field also
|
* The method's access flags (see {@link Opcodes}). This field also
|
||||||
* indicates if the method is synthetic and/or deprecated.
|
* indicates if the method is synthetic and/or deprecated.
|
||||||
*/
|
*/
|
||||||
public int access;
|
public int access;
|
||||||
@@ -77,9 +78,14 @@ public class MethodNode extends MethodVisitor {
|
|||||||
*/
|
*/
|
||||||
public List<String> exceptions;
|
public List<String> exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The method parameter info (access flags and name)
|
||||||
|
*/
|
||||||
|
public List<ParameterNode> parameters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The runtime visible annotations of this method. This list is a list of
|
* The runtime visible annotations of this method. This list is a list of
|
||||||
* {@link org.objectweb.asm.tree.AnnotationNode} objects. May be <tt>null</tt>.
|
* {@link AnnotationNode} objects. May be <tt>null</tt>.
|
||||||
*
|
*
|
||||||
* @associates org.objectweb.asm.tree.AnnotationNode
|
* @associates org.objectweb.asm.tree.AnnotationNode
|
||||||
* @label visible
|
* @label visible
|
||||||
@@ -88,16 +94,34 @@ public class MethodNode extends MethodVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The runtime invisible annotations of this method. This list is a list of
|
* The runtime invisible annotations of this method. This list is a list of
|
||||||
* {@link org.objectweb.asm.tree.AnnotationNode} objects. May be <tt>null</tt>.
|
* {@link AnnotationNode} objects. May be <tt>null</tt>.
|
||||||
*
|
*
|
||||||
* @associates org.objectweb.asm.tree.AnnotationNode
|
* @associates org.objectweb.asm.tree.AnnotationNode
|
||||||
* @label invisible
|
* @label invisible
|
||||||
*/
|
*/
|
||||||
public List<AnnotationNode> invisibleAnnotations;
|
public List<AnnotationNode> invisibleAnnotations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runtime visible type annotations of this method. This list is a list
|
||||||
|
* of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
|
||||||
|
*
|
||||||
|
* @associates org.objectweb.asm.tree.TypeAnnotationNode
|
||||||
|
* @label visible
|
||||||
|
*/
|
||||||
|
public List<TypeAnnotationNode> visibleTypeAnnotations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runtime invisible type annotations of this method. This list is a
|
||||||
|
* list of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
|
||||||
|
*
|
||||||
|
* @associates org.objectweb.asm.tree.TypeAnnotationNode
|
||||||
|
* @label invisible
|
||||||
|
*/
|
||||||
|
public List<TypeAnnotationNode> invisibleTypeAnnotations;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The non standard attributes of this method. This list is a list of
|
* The non standard attributes of this method. This list is a list of
|
||||||
* {@link org.objectweb.asm.Attribute} objects. May be <tt>null</tt>.
|
* {@link Attribute} objects. May be <tt>null</tt>.
|
||||||
*
|
*
|
||||||
* @associates org.objectweb.asm.Attribute
|
* @associates org.objectweb.asm.Attribute
|
||||||
*/
|
*/
|
||||||
@@ -108,14 +132,14 @@ public class MethodNode extends MethodVisitor {
|
|||||||
* a {@link Byte}, {@link Boolean}, {@link Character}, {@link Short},
|
* a {@link Byte}, {@link Boolean}, {@link Character}, {@link Short},
|
||||||
* {@link Integer}, {@link Long}, {@link Float}, {@link Double},
|
* {@link Integer}, {@link Long}, {@link Float}, {@link Double},
|
||||||
* {@link String} or {@link Type}, or an two elements String array (for
|
* {@link String} or {@link Type}, or an two elements String array (for
|
||||||
* enumeration values), a {@link org.objectweb.asm.tree.AnnotationNode}, or a {@link java.util.List} of
|
* enumeration values), a {@link AnnotationNode}, or a {@link List} of
|
||||||
* values of one of the preceding types. May be <tt>null</tt>.
|
* values of one of the preceding types. May be <tt>null</tt>.
|
||||||
*/
|
*/
|
||||||
public Object annotationDefault;
|
public Object annotationDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The runtime visible parameter annotations of this method. These lists are
|
* The runtime visible parameter annotations of this method. These lists are
|
||||||
* lists of {@link org.objectweb.asm.tree.AnnotationNode} objects. May be <tt>null</tt>.
|
* lists of {@link AnnotationNode} objects. May be <tt>null</tt>.
|
||||||
*
|
*
|
||||||
* @associates org.objectweb.asm.tree.AnnotationNode
|
* @associates org.objectweb.asm.tree.AnnotationNode
|
||||||
* @label invisible parameters
|
* @label invisible parameters
|
||||||
@@ -124,7 +148,7 @@ public class MethodNode extends MethodVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The runtime invisible parameter annotations of this method. These lists
|
* The runtime invisible parameter annotations of this method. These lists
|
||||||
* are lists of {@link org.objectweb.asm.tree.AnnotationNode} objects. May be <tt>null</tt>.
|
* are lists of {@link AnnotationNode} objects. May be <tt>null</tt>.
|
||||||
*
|
*
|
||||||
* @associates org.objectweb.asm.tree.AnnotationNode
|
* @associates org.objectweb.asm.tree.AnnotationNode
|
||||||
* @label visible parameters
|
* @label visible parameters
|
||||||
@@ -133,7 +157,7 @@ public class MethodNode extends MethodVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The instructions of this method. This list is a list of
|
* The instructions of this method. This list is a list of
|
||||||
* {@link org.objectweb.asm.tree.AbstractInsnNode} objects.
|
* {@link AbstractInsnNode} objects.
|
||||||
*
|
*
|
||||||
* @associates org.objectweb.asm.tree.AbstractInsnNode
|
* @associates org.objectweb.asm.tree.AbstractInsnNode
|
||||||
* @label instructions
|
* @label instructions
|
||||||
@@ -160,32 +184,48 @@ public class MethodNode extends MethodVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The local variables of this method. This list is a list of
|
* The local variables of this method. This list is a list of
|
||||||
* {@link org.objectweb.asm.tree.LocalVariableNode} objects. May be <tt>null</tt>
|
* {@link LocalVariableNode} objects. May be <tt>null</tt>
|
||||||
*
|
*
|
||||||
* @associates org.objectweb.asm.tree.LocalVariableNode
|
* @associates org.objectweb.asm.tree.LocalVariableNode
|
||||||
*/
|
*/
|
||||||
public List<LocalVariableNode> localVariables;
|
public List<LocalVariableNode> localVariables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The visible local variable annotations of this method. This list is a
|
||||||
|
* list of {@link LocalVariableAnnotationNode} objects. May be <tt>null</tt>
|
||||||
|
*
|
||||||
|
* @associates org.objectweb.asm.tree.LocalVariableAnnotationNode
|
||||||
|
*/
|
||||||
|
public List<LocalVariableAnnotationNode> visibleLocalVariableAnnotations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The invisible local variable annotations of this method. This list is a
|
||||||
|
* list of {@link LocalVariableAnnotationNode} objects. May be <tt>null</tt>
|
||||||
|
*
|
||||||
|
* @associates org.objectweb.asm.tree.LocalVariableAnnotationNode
|
||||||
|
*/
|
||||||
|
public List<LocalVariableAnnotationNode> invisibleLocalVariableAnnotations;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the accept method has been called on this object.
|
* If the accept method has been called on this object.
|
||||||
*/
|
*/
|
||||||
private boolean visited;
|
private boolean visited;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an uninitialized {@link org.objectweb.asm.tree.MethodNode}. <i>Subclasses must not
|
* Constructs an uninitialized {@link MethodNode}. <i>Subclasses must not
|
||||||
* use this constructor</i>. Instead, they must use the
|
* use this constructor</i>. Instead, they must use the
|
||||||
* {@link #MethodNode(int)} version.
|
* {@link #MethodNode(int)} version.
|
||||||
*/
|
*/
|
||||||
public MethodNode() {
|
public MethodNode() {
|
||||||
this(Opcodes.ASM4);
|
this(Opcodes.ASM5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an uninitialized {@link org.objectweb.asm.tree.MethodNode}.
|
* Constructs an uninitialized {@link MethodNode}.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* the ASM API version implemented by this visitor. Must be one
|
* the ASM API version implemented by this visitor. Must be one
|
||||||
* of {@link org.objectweb.asm.Opcodes#ASM4}.
|
* of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
|
||||||
*/
|
*/
|
||||||
public MethodNode(final int api) {
|
public MethodNode(final int api) {
|
||||||
super(api);
|
super(api);
|
||||||
@@ -193,12 +233,12 @@ public class MethodNode extends MethodVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.MethodNode}. <i>Subclasses must not use this
|
* Constructs a new {@link MethodNode}. <i>Subclasses must not use this
|
||||||
* constructor</i>. Instead, they must use the
|
* constructor</i>. Instead, they must use the
|
||||||
* {@link #MethodNode(int, int, String, String, String, String[])} version.
|
* {@link #MethodNode(int, int, String, String, String, String[])} version.
|
||||||
*
|
*
|
||||||
* @param access
|
* @param access
|
||||||
* the method's access flags (see {@link org.objectweb.asm.Opcodes}). This
|
* the method's access flags (see {@link Opcodes}). This
|
||||||
* parameter also indicates if the method is synthetic and/or
|
* parameter also indicates if the method is synthetic and/or
|
||||||
* deprecated.
|
* deprecated.
|
||||||
* @param name
|
* @param name
|
||||||
@@ -214,17 +254,17 @@ public class MethodNode extends MethodVisitor {
|
|||||||
*/
|
*/
|
||||||
public MethodNode(final int access, final String name, final String desc,
|
public MethodNode(final int access, final String name, final String desc,
|
||||||
final String signature, final String[] exceptions) {
|
final String signature, final String[] exceptions) {
|
||||||
this(Opcodes.ASM4, access, name, desc, signature, exceptions);
|
this(Opcodes.ASM5, access, name, desc, signature, exceptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.MethodNode}.
|
* Constructs a new {@link MethodNode}.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* the ASM API version implemented by this visitor. Must be one
|
* the ASM API version implemented by this visitor. Must be one
|
||||||
* of {@link org.objectweb.asm.Opcodes#ASM4}.
|
* of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
|
||||||
* @param access
|
* @param access
|
||||||
* the method's access flags (see {@link org.objectweb.asm.Opcodes}). This
|
* the method's access flags (see {@link Opcodes}). This
|
||||||
* parameter also indicates if the method is synthetic and/or
|
* parameter also indicates if the method is synthetic and/or
|
||||||
* deprecated.
|
* deprecated.
|
||||||
* @param name
|
* @param name
|
||||||
@@ -263,11 +303,18 @@ public class MethodNode extends MethodVisitor {
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public void visitParameter(String name, int access) {
|
||||||
|
if (parameters == null) {
|
||||||
|
parameters = new ArrayList<ParameterNode>(5);
|
||||||
|
}
|
||||||
|
parameters.add(new ParameterNode(name, access));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
@Override
|
||||||
public AnnotationVisitor visitAnnotationDefault() {
|
public AnnotationVisitor visitAnnotationDefault() {
|
||||||
return new AnnotationNode(new ArrayList<Object>(0) {
|
return new AnnotationNode(new ArrayList<Object>(0) {
|
||||||
private static final long serialVersionUID = 3618671528080057645L;
|
@Override
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean add(final Object o) {
|
public boolean add(final Object o) {
|
||||||
annotationDefault = o;
|
annotationDefault = o;
|
||||||
return super.add(o);
|
return super.add(o);
|
||||||
@@ -293,6 +340,24 @@ public class MethodNode extends MethodVisitor {
|
|||||||
return an;
|
return an;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AnnotationVisitor visitTypeAnnotation(int typeRef,
|
||||||
|
TypePath typePath, String desc, boolean visible) {
|
||||||
|
TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
|
||||||
|
if (visible) {
|
||||||
|
if (visibleTypeAnnotations == null) {
|
||||||
|
visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
|
||||||
|
}
|
||||||
|
visibleTypeAnnotations.add(an);
|
||||||
|
} else {
|
||||||
|
if (invisibleTypeAnnotations == null) {
|
||||||
|
invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
|
||||||
|
}
|
||||||
|
invisibleTypeAnnotations.add(an);
|
||||||
|
}
|
||||||
|
return an;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public AnnotationVisitor visitParameterAnnotation(final int parameter,
|
public AnnotationVisitor visitParameterAnnotation(final int parameter,
|
||||||
@@ -419,6 +484,33 @@ public class MethodNode extends MethodVisitor {
|
|||||||
instructions.add(new MultiANewArrayInsnNode(desc, dims));
|
instructions.add(new MultiANewArrayInsnNode(desc, dims));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AnnotationVisitor visitInsnAnnotation(int typeRef,
|
||||||
|
TypePath typePath, String desc, boolean visible) {
|
||||||
|
// Finds the last real instruction, i.e. the instruction targeted by
|
||||||
|
// this annotation.
|
||||||
|
AbstractInsnNode insn = instructions.getLast();
|
||||||
|
while (insn.getOpcode() == -1) {
|
||||||
|
insn = insn.getPrevious();
|
||||||
|
}
|
||||||
|
// Adds the annotation to this instruction.
|
||||||
|
TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
|
||||||
|
if (visible) {
|
||||||
|
if (insn.visibleTypeAnnotations == null) {
|
||||||
|
insn.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
insn.visibleTypeAnnotations.add(an);
|
||||||
|
} else {
|
||||||
|
if (insn.invisibleTypeAnnotations == null) {
|
||||||
|
insn.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
insn.invisibleTypeAnnotations.add(an);
|
||||||
|
}
|
||||||
|
return an;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitTryCatchBlock(final Label start, final Label end,
|
public void visitTryCatchBlock(final Label start, final Label end,
|
||||||
final Label handler, final String type) {
|
final Label handler, final String type) {
|
||||||
@@ -426,6 +518,27 @@ public class MethodNode extends MethodVisitor {
|
|||||||
getLabelNode(end), getLabelNode(handler), type));
|
getLabelNode(end), getLabelNode(handler), type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
|
||||||
|
TypePath typePath, String desc, boolean visible) {
|
||||||
|
TryCatchBlockNode tcb = tryCatchBlocks.get((typeRef & 0x00FFFF00) >> 8);
|
||||||
|
TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
|
||||||
|
if (visible) {
|
||||||
|
if (tcb.visibleTypeAnnotations == null) {
|
||||||
|
tcb.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
tcb.visibleTypeAnnotations.add(an);
|
||||||
|
} else {
|
||||||
|
if (tcb.invisibleTypeAnnotations == null) {
|
||||||
|
tcb.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
tcb.invisibleTypeAnnotations.add(an);
|
||||||
|
}
|
||||||
|
return an;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitLocalVariable(final String name, final String desc,
|
public void visitLocalVariable(final String name, final String desc,
|
||||||
final String signature, final Label start, final Label end,
|
final String signature, final Label start, final Label end,
|
||||||
@@ -434,6 +547,29 @@ public class MethodNode extends MethodVisitor {
|
|||||||
getLabelNode(start), getLabelNode(end), index));
|
getLabelNode(start), getLabelNode(end), index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
|
||||||
|
TypePath typePath, Label[] start, Label[] end, int[] index,
|
||||||
|
String desc, boolean visible) {
|
||||||
|
LocalVariableAnnotationNode an = new LocalVariableAnnotationNode(
|
||||||
|
typeRef, typePath, getLabelNodes(start), getLabelNodes(end),
|
||||||
|
index, desc);
|
||||||
|
if (visible) {
|
||||||
|
if (visibleLocalVariableAnnotations == null) {
|
||||||
|
visibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>(
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
visibleLocalVariableAnnotations.add(an);
|
||||||
|
} else {
|
||||||
|
if (invisibleLocalVariableAnnotations == null) {
|
||||||
|
invisibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>(
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
invisibleLocalVariableAnnotations.add(an);
|
||||||
|
}
|
||||||
|
return an;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitLineNumber(final int line, final Label start) {
|
public void visitLineNumber(final int line, final Label start) {
|
||||||
instructions.add(new LineNumberNode(line, getLabelNode(start)));
|
instructions.add(new LineNumberNode(line, getLabelNode(start)));
|
||||||
@@ -452,7 +588,7 @@ public class MethodNode extends MethodVisitor {
|
|||||||
/**
|
/**
|
||||||
* Returns the LabelNode corresponding to the given Label. Creates a new
|
* Returns the LabelNode corresponding to the given Label. Creates a new
|
||||||
* LabelNode if necessary. The default implementation of this method uses
|
* LabelNode if necessary. The default implementation of this method uses
|
||||||
* the {@link org.objectweb.asm.Label#info} field to store associations between labels and
|
* the {@link Label#info} field to store associations between labels and
|
||||||
* label nodes.
|
* label nodes.
|
||||||
*
|
*
|
||||||
* @param l
|
* @param l
|
||||||
@@ -497,10 +633,52 @@ public class MethodNode extends MethodVisitor {
|
|||||||
* versions of the ASM API than the given version.
|
* versions of the ASM API than the given version.
|
||||||
*
|
*
|
||||||
* @param api
|
* @param api
|
||||||
* an ASM API version. Must be one of {@link org.objectweb.asm.Opcodes#ASM4}.
|
* an ASM API version. Must be one of {@link Opcodes#ASM4} or
|
||||||
|
* {@link Opcodes#ASM5}.
|
||||||
*/
|
*/
|
||||||
public void check(final int api) {
|
public void check(final int api) {
|
||||||
// nothing to do
|
if (api == Opcodes.ASM4) {
|
||||||
|
if (visibleTypeAnnotations != null
|
||||||
|
&& visibleTypeAnnotations.size() > 0) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
if (invisibleTypeAnnotations != null
|
||||||
|
&& invisibleTypeAnnotations.size() > 0) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
int n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
TryCatchBlockNode tcb = tryCatchBlocks.get(i);
|
||||||
|
if (tcb.visibleTypeAnnotations != null
|
||||||
|
&& tcb.visibleTypeAnnotations.size() > 0) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
if (tcb.invisibleTypeAnnotations != null
|
||||||
|
&& tcb.invisibleTypeAnnotations.size() > 0) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < instructions.size(); ++i) {
|
||||||
|
AbstractInsnNode insn = instructions.get(i);
|
||||||
|
if (insn.visibleTypeAnnotations != null
|
||||||
|
&& insn.visibleTypeAnnotations.size() > 0) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
if (insn.invisibleTypeAnnotations != null
|
||||||
|
&& insn.invisibleTypeAnnotations.size() > 0) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (visibleLocalVariableAnnotations != null
|
||||||
|
&& visibleLocalVariableAnnotations.size() > 0) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
if (invisibleLocalVariableAnnotations != null
|
||||||
|
&& invisibleLocalVariableAnnotations.size() > 0) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -526,8 +704,14 @@ public class MethodNode extends MethodVisitor {
|
|||||||
* a method visitor.
|
* a method visitor.
|
||||||
*/
|
*/
|
||||||
public void accept(final MethodVisitor mv) {
|
public void accept(final MethodVisitor mv) {
|
||||||
// visits the method attributes
|
// visits the method parameters
|
||||||
int i, j, n;
|
int i, j, n;
|
||||||
|
n = parameters == null ? 0 : parameters.size();
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
ParameterNode parameter = parameters.get(i);
|
||||||
|
mv.visitParameter(parameter.name, parameter.access);
|
||||||
|
}
|
||||||
|
// visits the method attributes
|
||||||
if (annotationDefault != null) {
|
if (annotationDefault != null) {
|
||||||
AnnotationVisitor av = mv.visitAnnotationDefault();
|
AnnotationVisitor av = mv.visitAnnotationDefault();
|
||||||
AnnotationNode.accept(av, null, annotationDefault);
|
AnnotationNode.accept(av, null, annotationDefault);
|
||||||
@@ -545,6 +729,19 @@ public class MethodNode extends MethodVisitor {
|
|||||||
AnnotationNode an = invisibleAnnotations.get(i);
|
AnnotationNode an = invisibleAnnotations.get(i);
|
||||||
an.accept(mv.visitAnnotation(an.desc, false));
|
an.accept(mv.visitAnnotation(an.desc, false));
|
||||||
}
|
}
|
||||||
|
n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
TypeAnnotationNode an = visibleTypeAnnotations.get(i);
|
||||||
|
an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
|
||||||
|
true));
|
||||||
|
}
|
||||||
|
n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
|
||||||
|
.size();
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
|
||||||
|
an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
|
||||||
|
false));
|
||||||
|
}
|
||||||
n = visibleParameterAnnotations == null ? 0
|
n = visibleParameterAnnotations == null ? 0
|
||||||
: visibleParameterAnnotations.length;
|
: visibleParameterAnnotations.length;
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
@@ -582,6 +779,7 @@ public class MethodNode extends MethodVisitor {
|
|||||||
// visits try catch blocks
|
// visits try catch blocks
|
||||||
n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();
|
n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
|
tryCatchBlocks.get(i).updateIndex(i);
|
||||||
tryCatchBlocks.get(i).accept(mv);
|
tryCatchBlocks.get(i).accept(mv);
|
||||||
}
|
}
|
||||||
// visits instructions
|
// visits instructions
|
||||||
@@ -591,6 +789,17 @@ public class MethodNode extends MethodVisitor {
|
|||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
localVariables.get(i).accept(mv);
|
localVariables.get(i).accept(mv);
|
||||||
}
|
}
|
||||||
|
// visits local variable annotations
|
||||||
|
n = visibleLocalVariableAnnotations == null ? 0
|
||||||
|
: visibleLocalVariableAnnotations.size();
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
visibleLocalVariableAnnotations.get(i).accept(mv, true);
|
||||||
|
}
|
||||||
|
n = invisibleLocalVariableAnnotations == null ? 0
|
||||||
|
: invisibleLocalVariableAnnotations.size();
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
invisibleLocalVariableAnnotations.get(i).accept(mv, false);
|
||||||
|
}
|
||||||
// visits maxs
|
// visits maxs
|
||||||
mv.visitMaxs(maxStack, maxLocals);
|
mv.visitMaxs(maxStack, maxLocals);
|
||||||
visited = true;
|
visited = true;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class MultiANewArrayInsnNode extends AbstractInsnNode {
|
|||||||
public int dims;
|
public int dims;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.MultiANewArrayInsnNode}.
|
* Constructs a new {@link MultiANewArrayInsnNode}.
|
||||||
*
|
*
|
||||||
* @param desc
|
* @param desc
|
||||||
* an array type descriptor (see {@link org.objectweb.asm.Type}).
|
* an array type descriptor (see {@link org.objectweb.asm.Type}).
|
||||||
@@ -73,11 +73,12 @@ public class MultiANewArrayInsnNode extends AbstractInsnNode {
|
|||||||
@Override
|
@Override
|
||||||
public void accept(final MethodVisitor mv) {
|
public void accept(final MethodVisitor mv) {
|
||||||
mv.visitMultiANewArrayInsn(desc, dims);
|
mv.visitMultiANewArrayInsn(desc, dims);
|
||||||
|
acceptAnnotations(mv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
||||||
return new MultiANewArrayInsnNode(desc, dims);
|
return new MultiANewArrayInsnNode(desc, dims).cloneAnnotations(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+48
-8
@@ -1,5 +1,4 @@
|
|||||||
<html>
|
/***
|
||||||
<!--
|
|
||||||
* ASM: a very small and fast Java bytecode manipulation framework
|
* ASM: a very small and fast Java bytecode manipulation framework
|
||||||
* Copyright (c) 2000-2011 INRIA, France Telecom
|
* Copyright (c) 2000-2011 INRIA, France Telecom
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
@@ -27,10 +26,51 @@
|
|||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
-->
|
*/
|
||||||
<body>
|
package org.objectweb.asm.tree;
|
||||||
Provides support for type signatures.
|
|
||||||
|
|
||||||
@since ASM 2.0
|
import org.objectweb.asm.MethodVisitor;
|
||||||
</body>
|
|
||||||
</html>
|
/**
|
||||||
|
* A node that represents a parameter access and name.
|
||||||
|
*
|
||||||
|
* @author Remi Forax
|
||||||
|
*/
|
||||||
|
public class ParameterNode {
|
||||||
|
/**
|
||||||
|
* The parameter's name.
|
||||||
|
*/
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter's access flags (see {@link org.objectweb.asm.Opcodes}).
|
||||||
|
* Valid values are <tt>ACC_FINAL</tt>, <tt>ACC_SYNTHETIC</tt> and
|
||||||
|
* <tt>ACC_MANDATED</tt>.
|
||||||
|
*/
|
||||||
|
public int access;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link ParameterNode}.
|
||||||
|
*
|
||||||
|
* @param access
|
||||||
|
* The parameter's access flags. Valid values are
|
||||||
|
* <tt>ACC_FINAL</tt>, <tt>ACC_SYNTHETIC</tt> or/and
|
||||||
|
* <tt>ACC_MANDATED</tt> (see {@link org.objectweb.asm.Opcodes}).
|
||||||
|
* @param name
|
||||||
|
* the parameter's name.
|
||||||
|
*/
|
||||||
|
public ParameterNode(final String name, final int access) {
|
||||||
|
this.name = name;
|
||||||
|
this.access = access;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the given visitor visit this parameter declaration.
|
||||||
|
*
|
||||||
|
* @param mv
|
||||||
|
* a method visitor.
|
||||||
|
*/
|
||||||
|
public void accept(final MethodVisitor mv) {
|
||||||
|
mv.visitParameter(name, access);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,12 +62,12 @@ public class TableSwitchInsnNode extends AbstractInsnNode {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Beginnings of the handler blocks. This list is a list of
|
* Beginnings of the handler blocks. This list is a list of
|
||||||
* {@link org.objectweb.asm.tree.LabelNode} objects.
|
* {@link LabelNode} objects.
|
||||||
*/
|
*/
|
||||||
public List<LabelNode> labels;
|
public List<LabelNode> labels;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.TableSwitchInsnNode}.
|
* Constructs a new {@link TableSwitchInsnNode}.
|
||||||
*
|
*
|
||||||
* @param min
|
* @param min
|
||||||
* the minimum key value.
|
* the minimum key value.
|
||||||
@@ -103,11 +103,12 @@ public class TableSwitchInsnNode extends AbstractInsnNode {
|
|||||||
labels[i] = this.labels.get(i).getLabel();
|
labels[i] = this.labels.get(i).getLabel();
|
||||||
}
|
}
|
||||||
mv.visitTableSwitchInsn(min, max, dflt.getLabel(), labels);
|
mv.visitTableSwitchInsn(min, max, dflt.getLabel(), labels);
|
||||||
|
acceptAnnotations(mv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
||||||
return new TableSwitchInsnNode(min, max, clone(dflt, labels), clone(
|
return new TableSwitchInsnNode(min, max, clone(dflt, labels), clone(
|
||||||
this.labels, labels));
|
this.labels, labels)).cloneAnnotations(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,6 +29,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.objectweb.asm.tree;
|
package org.objectweb.asm.tree;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,7 +62,27 @@ public class TryCatchBlockNode {
|
|||||||
public String type;
|
public String type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.TryCatchBlockNode}.
|
* The runtime visible type annotations on the exception handler type. This
|
||||||
|
* list is a list of {@link TypeAnnotationNode} objects. May be
|
||||||
|
* <tt>null</tt>.
|
||||||
|
*
|
||||||
|
* @associates org.objectweb.asm.tree.TypeAnnotationNode
|
||||||
|
* @label visible
|
||||||
|
*/
|
||||||
|
public List<TypeAnnotationNode> visibleTypeAnnotations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runtime invisible type annotations on the exception handler type.
|
||||||
|
* This list is a list of {@link TypeAnnotationNode} objects. May be
|
||||||
|
* <tt>null</tt>.
|
||||||
|
*
|
||||||
|
* @associates org.objectweb.asm.tree.TypeAnnotationNode
|
||||||
|
* @label invisible
|
||||||
|
*/
|
||||||
|
public List<TypeAnnotationNode> invisibleTypeAnnotations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link TryCatchBlockNode}.
|
||||||
*
|
*
|
||||||
* @param start
|
* @param start
|
||||||
* beginning of the exception handler's scope (inclusive).
|
* beginning of the exception handler's scope (inclusive).
|
||||||
@@ -81,6 +103,29 @@ public class TryCatchBlockNode {
|
|||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the index of this try catch block in the method's list of try
|
||||||
|
* catch block nodes. This index maybe stored in the 'target' field of the
|
||||||
|
* type annotations of this block.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the new index of this try catch block in the method's list of
|
||||||
|
* try catch block nodes.
|
||||||
|
*/
|
||||||
|
public void updateIndex(final int index) {
|
||||||
|
int newTypeRef = 0x42000000 | (index << 8);
|
||||||
|
if (visibleTypeAnnotations != null) {
|
||||||
|
for (TypeAnnotationNode tan : visibleTypeAnnotations) {
|
||||||
|
tan.typeRef = newTypeRef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (invisibleTypeAnnotations != null) {
|
||||||
|
for (TypeAnnotationNode tan : invisibleTypeAnnotations) {
|
||||||
|
tan.typeRef = newTypeRef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the given visitor visit this try catch block.
|
* Makes the given visitor visit this try catch block.
|
||||||
*
|
*
|
||||||
@@ -90,5 +135,19 @@ public class TryCatchBlockNode {
|
|||||||
public void accept(final MethodVisitor mv) {
|
public void accept(final MethodVisitor mv) {
|
||||||
mv.visitTryCatchBlock(start.getLabel(), end.getLabel(),
|
mv.visitTryCatchBlock(start.getLabel(), end.getLabel(),
|
||||||
handler == null ? null : handler.getLabel(), type);
|
handler == null ? null : handler.getLabel(), type);
|
||||||
|
int n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations
|
||||||
|
.size();
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
TypeAnnotationNode an = visibleTypeAnnotations.get(i);
|
||||||
|
an.accept(mv.visitTryCatchAnnotation(an.typeRef, an.typePath,
|
||||||
|
an.desc, true));
|
||||||
|
}
|
||||||
|
n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
|
||||||
|
.size();
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
|
||||||
|
an.accept(mv.visitTryCatchAnnotation(an.typeRef, an.typePath,
|
||||||
|
an.desc, false));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
/***
|
||||||
|
* ASM: a very small and fast Java bytecode manipulation framework
|
||||||
|
* Copyright (c) 2000-2011 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.tree;
|
||||||
|
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import org.objectweb.asm.TypePath;
|
||||||
|
import org.objectweb.asm.TypeReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A node that represents a type annotationn.
|
||||||
|
*
|
||||||
|
* @author Eric Bruneton
|
||||||
|
*/
|
||||||
|
public class TypeAnnotationNode extends AnnotationNode {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A reference to the annotated type. See {@link TypeReference}.
|
||||||
|
*/
|
||||||
|
public int typeRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path to the annotated type argument, wildcard bound, array element
|
||||||
|
* type, or static outer type within the referenced type. May be
|
||||||
|
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||||
|
*/
|
||||||
|
public TypePath typePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link AnnotationNode}. <i>Subclasses must not use this
|
||||||
|
* constructor</i>. Instead, they must use the
|
||||||
|
* {@link #TypeAnnotationNode(int, int, TypePath, String)} version.
|
||||||
|
*
|
||||||
|
* @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
|
||||||
|
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||||
|
* @param desc
|
||||||
|
* the class descriptor of the annotation class.
|
||||||
|
*/
|
||||||
|
public TypeAnnotationNode(final int typeRef, final TypePath typePath,
|
||||||
|
final String desc) {
|
||||||
|
this(Opcodes.ASM5, typeRef, typePath, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link AnnotationNode}.
|
||||||
|
*
|
||||||
|
* @param api
|
||||||
|
* the ASM API version implemented by this visitor. Must be one
|
||||||
|
* of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
|
||||||
|
* @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
|
||||||
|
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||||
|
* @param desc
|
||||||
|
* the class descriptor of the annotation class.
|
||||||
|
*/
|
||||||
|
public TypeAnnotationNode(final int api, final int typeRef,
|
||||||
|
final TypePath typePath, final String desc) {
|
||||||
|
super(api, desc);
|
||||||
|
this.typeRef = typeRef;
|
||||||
|
this.typePath = typePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,7 +48,7 @@ public class TypeInsnNode extends AbstractInsnNode {
|
|||||||
public String desc;
|
public String desc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.TypeInsnNode}.
|
* Constructs a new {@link TypeInsnNode}.
|
||||||
*
|
*
|
||||||
* @param opcode
|
* @param opcode
|
||||||
* the opcode of the type instruction to be constructed. This
|
* the opcode of the type instruction to be constructed. This
|
||||||
@@ -81,10 +81,11 @@ public class TypeInsnNode extends AbstractInsnNode {
|
|||||||
@Override
|
@Override
|
||||||
public void accept(final MethodVisitor mv) {
|
public void accept(final MethodVisitor mv) {
|
||||||
mv.visitTypeInsn(opcode, desc);
|
mv.visitTypeInsn(opcode, desc);
|
||||||
|
acceptAnnotations(mv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
||||||
return new TypeInsnNode(opcode, desc);
|
return new TypeInsnNode(opcode, desc).cloneAnnotations(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ public class VarInsnNode extends AbstractInsnNode {
|
|||||||
public int var;
|
public int var;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link org.objectweb.asm.tree.VarInsnNode}.
|
* Constructs a new {@link VarInsnNode}.
|
||||||
*
|
*
|
||||||
* @param opcode
|
* @param opcode
|
||||||
* the opcode of the local variable instruction to be
|
* the opcode of the local variable instruction to be
|
||||||
@@ -84,10 +84,11 @@ public class VarInsnNode extends AbstractInsnNode {
|
|||||||
@Override
|
@Override
|
||||||
public void accept(final MethodVisitor mv) {
|
public void accept(final MethodVisitor mv) {
|
||||||
mv.visitVarInsn(opcode, var);
|
mv.visitVarInsn(opcode, var);
|
||||||
|
acceptAnnotations(mv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
|
||||||
return new VarInsnNode(opcode, var);
|
return new VarInsnNode(opcode, var).cloneAnnotations(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user