richie
7 years ago
31 changed files with 1 additions and 16102 deletions
@ -1,169 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* A visitor to visit a Java annotation. The methods of this class must be |
||||
* called in the following order: ( <tt>visit</tt> | <tt>visitEnum</tt> | |
||||
* <tt>visitAnnotation</tt> | <tt>visitArray</tt> )* <tt>visitEnd</tt>. |
||||
* |
||||
* @author Eric Bruneton |
||||
* @author Eugene Kuleshov |
||||
*/ |
||||
public abstract class AnnotationVisitor { |
||||
|
||||
/** |
||||
* The ASM API version implemented by this visitor. The value of this field |
||||
* must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. |
||||
*/ |
||||
protected final int api; |
||||
|
||||
/** |
||||
* The annotation visitor to which this visitor must delegate method calls. |
||||
* May be null. |
||||
*/ |
||||
protected AnnotationVisitor av; |
||||
|
||||
/** |
||||
* Constructs a new {@link AnnotationVisitor}. |
||||
* |
||||
* @param api |
||||
* the ASM API version implemented by this visitor. Must be one |
||||
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. |
||||
*/ |
||||
public AnnotationVisitor(final int api) { |
||||
this(api, null); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a new {@link AnnotationVisitor}. |
||||
* |
||||
* @param api |
||||
* the ASM API version implemented by this visitor. Must be one |
||||
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. |
||||
* @param av |
||||
* the annotation visitor to which this visitor must delegate |
||||
* method calls. May be null. |
||||
*/ |
||||
public AnnotationVisitor(final int api, final AnnotationVisitor av) { |
||||
if (api < Opcodes.ASM4 || api > Opcodes.ASM6) { |
||||
throw new IllegalArgumentException(); |
||||
} |
||||
this.api = api; |
||||
this.av = av; |
||||
} |
||||
|
||||
/** |
||||
* Visits a primitive value of the annotation. |
||||
* |
||||
* @param name |
||||
* the value name. |
||||
* @param value |
||||
* the actual value, whose type must be {@link Byte}, |
||||
* {@link Boolean}, {@link Character}, {@link Short}, |
||||
* {@link Integer} , {@link Long}, {@link Float}, {@link Double}, |
||||
* {@link String} or {@link Type} of OBJECT or ARRAY sort. This |
||||
* value can also be an array of byte, boolean, short, char, int, |
||||
* long, float or double values (this is equivalent to using |
||||
* {@link #visitArray visitArray} and visiting each array element |
||||
* in turn, but is more convenient). |
||||
*/ |
||||
public void visit(String name, Object value) { |
||||
if (av != null) { |
||||
av.visit(name, value); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits an enumeration value of the annotation. |
||||
* |
||||
* @param name |
||||
* the value name. |
||||
* @param desc |
||||
* the class descriptor of the enumeration class. |
||||
* @param value |
||||
* the actual enumeration value. |
||||
*/ |
||||
public void visitEnum(String name, String desc, String value) { |
||||
if (av != null) { |
||||
av.visitEnum(name, desc, value); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits a nested annotation value of the annotation. |
||||
* |
||||
* @param name |
||||
* the value name. |
||||
* @param desc |
||||
* the class descriptor of the nested annotation class. |
||||
* @return a visitor to visit the actual nested annotation value, or |
||||
* <tt>null</tt> if this visitor is not interested in visiting this |
||||
* nested annotation. <i>The nested annotation value must be fully |
||||
* visited before calling other methods on this annotation |
||||
* visitor</i>. |
||||
*/ |
||||
public AnnotationVisitor visitAnnotation(String name, String desc) { |
||||
if (av != null) { |
||||
return av.visitAnnotation(name, desc); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Visits an array value of the annotation. Note that arrays of primitive |
||||
* types (such as byte, boolean, short, char, int, long, float or double) |
||||
* can be passed as value to {@link #visit visit}. This is what |
||||
* {@link ClassReader} does. |
||||
* |
||||
* @param name |
||||
* the value name. |
||||
* @return a visitor to visit the actual array value elements, or |
||||
* <tt>null</tt> if this visitor is not interested in visiting these |
||||
* values. The 'name' parameters passed to the methods of this |
||||
* visitor are ignored. <i>All the array values must be visited |
||||
* before calling other methods on this annotation visitor</i>. |
||||
*/ |
||||
public AnnotationVisitor visitArray(String name) { |
||||
if (av != null) { |
||||
return av.visitArray(name); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Visits the end of the annotation. |
||||
*/ |
||||
public void visitEnd() { |
||||
if (av != null) { |
||||
av.visitEnd(); |
||||
} |
||||
} |
||||
} |
@ -1,371 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* An {@link AnnotationVisitor} that generates annotations in bytecode form. |
||||
* |
||||
* @author Eric Bruneton |
||||
* @author Eugene Kuleshov |
||||
*/ |
||||
final class AnnotationWriter extends AnnotationVisitor { |
||||
|
||||
/** |
||||
* The class writer to which this annotation must be added. |
||||
*/ |
||||
private final ClassWriter cw; |
||||
|
||||
/** |
||||
* The number of values in this annotation. |
||||
*/ |
||||
private int size; |
||||
|
||||
/** |
||||
* <tt>true<tt> if values are named, <tt>false</tt> otherwise. Annotation |
||||
* writers used for annotation default and annotation arrays use unnamed |
||||
* values. |
||||
*/ |
||||
private final boolean named; |
||||
|
||||
/** |
||||
* The annotation values in bytecode form. This byte vector only contains |
||||
* the values themselves, i.e. the number of values must be stored as a |
||||
* unsigned short just before these bytes. |
||||
*/ |
||||
private final ByteVector bv; |
||||
|
||||
/** |
||||
* The byte vector to be used to store the number of values of this |
||||
* annotation. See {@link #bv}. |
||||
*/ |
||||
private final ByteVector parent; |
||||
|
||||
/** |
||||
* Where the number of values of this annotation must be stored in |
||||
* {@link #parent}. |
||||
*/ |
||||
private final int offset; |
||||
|
||||
/** |
||||
* Next annotation writer. This field is used to store annotation lists. |
||||
*/ |
||||
AnnotationWriter next; |
||||
|
||||
/** |
||||
* Previous annotation writer. This field is used to store annotation lists. |
||||
*/ |
||||
AnnotationWriter prev; |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Constructs a new {@link AnnotationWriter}. |
||||
* |
||||
* @param cw |
||||
* the class writer to which this annotation must be added. |
||||
* @param named |
||||
* <tt>true<tt> if values are named, <tt>false</tt> otherwise. |
||||
* @param bv |
||||
* where the annotation values must be stored. |
||||
* @param parent |
||||
* where the number of annotation values must be stored. |
||||
* @param offset |
||||
* where in <tt>parent</tt> the number of annotation values must |
||||
* be stored. |
||||
*/ |
||||
AnnotationWriter(final ClassWriter cw, final boolean named, |
||||
final ByteVector bv, final ByteVector parent, final int offset) { |
||||
super(Opcodes.ASM6); |
||||
this.cw = cw; |
||||
this.named = named; |
||||
this.bv = bv; |
||||
this.parent = parent; |
||||
this.offset = offset; |
||||
} |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Implementation of the AnnotationVisitor abstract class
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@Override |
||||
public void visit(final String name, final Object value) { |
||||
++size; |
||||
if (named) { |
||||
bv.putShort(cw.newUTF8(name)); |
||||
} |
||||
if (value instanceof String) { |
||||
bv.put12('s', cw.newUTF8((String) value)); |
||||
} else if (value instanceof Byte) { |
||||
bv.put12('B', cw.newInteger(((Byte) value).byteValue()).index); |
||||
} else if (value instanceof Boolean) { |
||||
int v = ((Boolean) value).booleanValue() ? 1 : 0; |
||||
bv.put12('Z', cw.newInteger(v).index); |
||||
} else if (value instanceof Character) { |
||||
bv.put12('C', cw.newInteger(((Character) value).charValue()).index); |
||||
} else if (value instanceof Short) { |
||||
bv.put12('S', cw.newInteger(((Short) value).shortValue()).index); |
||||
} else if (value instanceof Type) { |
||||
bv.put12('c', cw.newUTF8(((Type) value).getDescriptor())); |
||||
} else if (value instanceof byte[]) { |
||||
byte[] v = (byte[]) value; |
||||
bv.put12('[', v.length); |
||||
for (int i = 0; i < v.length; i++) { |
||||
bv.put12('B', cw.newInteger(v[i]).index); |
||||
} |
||||
} else if (value instanceof boolean[]) { |
||||
boolean[] v = (boolean[]) value; |
||||
bv.put12('[', v.length); |
||||
for (int i = 0; i < v.length; i++) { |
||||
bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index); |
||||
} |
||||
} else if (value instanceof short[]) { |
||||
short[] v = (short[]) value; |
||||
bv.put12('[', v.length); |
||||
for (int i = 0; i < v.length; i++) { |
||||
bv.put12('S', cw.newInteger(v[i]).index); |
||||
} |
||||
} else if (value instanceof char[]) { |
||||
char[] v = (char[]) value; |
||||
bv.put12('[', v.length); |
||||
for (int i = 0; i < v.length; i++) { |
||||
bv.put12('C', cw.newInteger(v[i]).index); |
||||
} |
||||
} else if (value instanceof int[]) { |
||||
int[] v = (int[]) value; |
||||
bv.put12('[', v.length); |
||||
for (int i = 0; i < v.length; i++) { |
||||
bv.put12('I', cw.newInteger(v[i]).index); |
||||
} |
||||
} else if (value instanceof long[]) { |
||||
long[] v = (long[]) value; |
||||
bv.put12('[', v.length); |
||||
for (int i = 0; i < v.length; i++) { |
||||
bv.put12('J', cw.newLong(v[i]).index); |
||||
} |
||||
} else if (value instanceof float[]) { |
||||
float[] v = (float[]) value; |
||||
bv.put12('[', v.length); |
||||
for (int i = 0; i < v.length; i++) { |
||||
bv.put12('F', cw.newFloat(v[i]).index); |
||||
} |
||||
} else if (value instanceof double[]) { |
||||
double[] v = (double[]) value; |
||||
bv.put12('[', v.length); |
||||
for (int i = 0; i < v.length; i++) { |
||||
bv.put12('D', cw.newDouble(v[i]).index); |
||||
} |
||||
} else { |
||||
Item i = cw.newConstItem(value); |
||||
bv.put12(".s.IFJDCS".charAt(i.type), i.index); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void visitEnum(final String name, final String desc, |
||||
final String value) { |
||||
++size; |
||||
if (named) { |
||||
bv.putShort(cw.newUTF8(name)); |
||||
} |
||||
bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value)); |
||||
} |
||||
|
||||
@Override |
||||
public AnnotationVisitor visitAnnotation(final String name, |
||||
final String desc) { |
||||
++size; |
||||
if (named) { |
||||
bv.putShort(cw.newUTF8(name)); |
||||
} |
||||
// write tag and type, and reserve space for values count
|
||||
bv.put12('@', cw.newUTF8(desc)).putShort(0); |
||||
return new AnnotationWriter(cw, true, bv, bv, bv.length - 2); |
||||
} |
||||
|
||||
@Override |
||||
public AnnotationVisitor visitArray(final String name) { |
||||
++size; |
||||
if (named) { |
||||
bv.putShort(cw.newUTF8(name)); |
||||
} |
||||
// write tag, and reserve space for array size
|
||||
bv.put12('[', 0); |
||||
return new AnnotationWriter(cw, false, bv, bv, bv.length - 2); |
||||
} |
||||
|
||||
@Override |
||||
public void visitEnd() { |
||||
if (parent != null) { |
||||
byte[] data = parent.data; |
||||
data[offset] = (byte) (size >>> 8); |
||||
data[offset + 1] = (byte) size; |
||||
} |
||||
} |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Utility methods
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Returns the size of this annotation writer list. |
||||
* |
||||
* @return the size of this annotation writer list. |
||||
*/ |
||||
int getSize() { |
||||
int size = 0; |
||||
AnnotationWriter aw = this; |
||||
while (aw != null) { |
||||
size += aw.bv.length; |
||||
aw = aw.next; |
||||
} |
||||
return size; |
||||
} |
||||
|
||||
/** |
||||
* Puts the annotations of this annotation writer list into the given byte |
||||
* vector. |
||||
* |
||||
* @param out |
||||
* where the annotations must be put. |
||||
*/ |
||||
void put(final ByteVector out) { |
||||
int n = 0; |
||||
int size = 2; |
||||
AnnotationWriter aw = this; |
||||
AnnotationWriter last = null; |
||||
while (aw != null) { |
||||
++n; |
||||
size += aw.bv.length; |
||||
aw.visitEnd(); // in case user forgot to call visitEnd
|
||||
aw.prev = last; |
||||
last = aw; |
||||
aw = aw.next; |
||||
} |
||||
out.putInt(size); |
||||
out.putShort(n); |
||||
aw = last; |
||||
while (aw != null) { |
||||
out.putByteArray(aw.bv.data, 0, aw.bv.length); |
||||
aw = aw.prev; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Puts the given annotation lists into the given byte vector. |
||||
* |
||||
* @param panns |
||||
* an array of annotation writer lists. |
||||
* @param off |
||||
* index of the first annotation to be written. |
||||
* @param out |
||||
* where the annotations must be put. |
||||
*/ |
||||
static void put(final AnnotationWriter[] panns, final int off, |
||||
final ByteVector out) { |
||||
int size = 1 + 2 * (panns.length - off); |
||||
for (int i = off; i < panns.length; ++i) { |
||||
size += panns[i] == null ? 0 : panns[i].getSize(); |
||||
} |
||||
out.putInt(size).putByte(panns.length - off); |
||||
for (int i = off; i < panns.length; ++i) { |
||||
AnnotationWriter aw = panns[i]; |
||||
AnnotationWriter last = null; |
||||
int n = 0; |
||||
while (aw != null) { |
||||
++n; |
||||
aw.visitEnd(); // in case user forgot to call visitEnd
|
||||
aw.prev = last; |
||||
last = aw; |
||||
aw = aw.next; |
||||
} |
||||
out.putShort(n); |
||||
aw = last; |
||||
while (aw != null) { |
||||
out.putByteArray(aw.bv.data, 0, aw.bv.length); |
||||
aw = aw.prev; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 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); |
||||
} |
||||
} |
||||
} |
@ -1,255 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* A non standard class, field, method or code attribute. |
||||
* |
||||
* @author Eric Bruneton |
||||
* @author Eugene Kuleshov |
||||
*/ |
||||
public class Attribute { |
||||
|
||||
/** |
||||
* The type of this attribute. |
||||
*/ |
||||
public final String type; |
||||
|
||||
/** |
||||
* The raw value of this attribute, used only for unknown attributes. |
||||
*/ |
||||
byte[] value; |
||||
|
||||
/** |
||||
* The next attribute in this attribute list. May be <tt>null</tt>. |
||||
*/ |
||||
Attribute next; |
||||
|
||||
/** |
||||
* Constructs a new empty attribute. |
||||
* |
||||
* @param type |
||||
* the type of the attribute. |
||||
*/ |
||||
protected Attribute(final String type) { |
||||
this.type = type; |
||||
} |
||||
|
||||
/** |
||||
* Returns <tt>true</tt> if this type of attribute is unknown. The default |
||||
* implementation of this method always returns <tt>true</tt>. |
||||
* |
||||
* @return <tt>true</tt> if this type of attribute is unknown. |
||||
*/ |
||||
public boolean isUnknown() { |
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* Returns <tt>true</tt> if this type of attribute is a code attribute. |
||||
* |
||||
* @return <tt>true</tt> if this type of attribute is a code attribute. |
||||
*/ |
||||
public boolean isCodeAttribute() { |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Returns the labels corresponding to this attribute. |
||||
* |
||||
* @return the labels corresponding to this attribute, or <tt>null</tt> if |
||||
* this attribute is not a code attribute that contains labels. |
||||
*/ |
||||
protected Label[] getLabels() { |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Reads a {@link #type type} attribute. This method must return a |
||||
* <i>new</i> {@link Attribute} object, of type {@link #type type}, |
||||
* corresponding to the <tt>len</tt> bytes starting at the given offset, in |
||||
* the given class reader. |
||||
* |
||||
* @param cr |
||||
* the class that contains the attribute to be read. |
||||
* @param off |
||||
* index of the first byte of the attribute's content in |
||||
* {@link ClassReader#b cr.b}. The 6 attribute header bytes, |
||||
* containing the type and the length of the attribute, are not |
||||
* taken into account here. |
||||
* @param len |
||||
* the length of the attribute's content. |
||||
* @param buf |
||||
* buffer to be used to call {@link ClassReader#readUTF8 |
||||
* readUTF8}, {@link ClassReader#readClass(int,char[]) readClass} |
||||
* or {@link ClassReader#readConst readConst}. |
||||
* @param codeOff |
||||
* index of the first byte of code's attribute content in |
||||
* {@link ClassReader#b cr.b}, or -1 if the attribute to be read |
||||
* is not a code attribute. The 6 attribute header bytes, |
||||
* containing the type and the length of the attribute, are not |
||||
* taken into account here. |
||||
* @param labels |
||||
* the labels of the method's code, or <tt>null</tt> if the |
||||
* attribute to be read is not a code attribute. |
||||
* @return a <i>new</i> {@link Attribute} object corresponding to the given |
||||
* bytes. |
||||
*/ |
||||
protected Attribute read(final ClassReader cr, final int off, |
||||
final int len, final char[] buf, final int codeOff, |
||||
final Label[] labels) { |
||||
Attribute attr = new Attribute(type); |
||||
attr.value = new byte[len]; |
||||
System.arraycopy(cr.b, off, attr.value, 0, len); |
||||
return attr; |
||||
} |
||||
|
||||
/** |
||||
* Returns the byte array form of this attribute. |
||||
* |
||||
* @param cw |
||||
* the class to which this attribute must be added. This |
||||
* parameter can be used to add to the constant pool of this |
||||
* class the items that corresponds to this attribute. |
||||
* @param code |
||||
* the bytecode of the method corresponding to this code |
||||
* attribute, or <tt>null</tt> if this attribute is not a code |
||||
* attributes. |
||||
* @param len |
||||
* the length of the bytecode of the method corresponding to this |
||||
* code attribute, or <tt>null</tt> if this attribute is not a |
||||
* code attribute. |
||||
* @param maxStack |
||||
* the maximum stack size of the method corresponding to this |
||||
* code attribute, or -1 if this attribute is not a code |
||||
* attribute. |
||||
* @param maxLocals |
||||
* the maximum number of local variables of the method |
||||
* corresponding to this code attribute, or -1 if this attribute |
||||
* is not a code attribute. |
||||
* @return the byte array form of this attribute. |
||||
*/ |
||||
protected ByteVector write(final ClassWriter cw, final byte[] code, |
||||
final int len, final int maxStack, final int maxLocals) { |
||||
ByteVector v = new ByteVector(); |
||||
v.data = value; |
||||
v.length = value.length; |
||||
return v; |
||||
} |
||||
|
||||
/** |
||||
* Returns the length of the attribute list that begins with this attribute. |
||||
* |
||||
* @return the length of the attribute list that begins with this attribute. |
||||
*/ |
||||
final int getCount() { |
||||
int count = 0; |
||||
Attribute attr = this; |
||||
while (attr != null) { |
||||
count += 1; |
||||
attr = attr.next; |
||||
} |
||||
return count; |
||||
} |
||||
|
||||
/** |
||||
* Returns the size of all the attributes in this attribute list. |
||||
* |
||||
* @param cw |
||||
* the class writer to be used to convert the attributes into |
||||
* byte arrays, with the {@link #write write} method. |
||||
* @param code |
||||
* the bytecode of the method corresponding to these code |
||||
* attributes, or <tt>null</tt> if these attributes are not code |
||||
* attributes. |
||||
* @param len |
||||
* the length of the bytecode of the method corresponding to |
||||
* these code attributes, or <tt>null</tt> if these attributes |
||||
* are not code attributes. |
||||
* @param maxStack |
||||
* the maximum stack size of the method corresponding to these |
||||
* code attributes, or -1 if these attributes are not code |
||||
* attributes. |
||||
* @param maxLocals |
||||
* the maximum number of local variables of the method |
||||
* corresponding to these code attributes, or -1 if these |
||||
* attributes are not code attributes. |
||||
* @return the size of all the attributes in this attribute list. This size |
||||
* includes the size of the attribute headers. |
||||
*/ |
||||
final int getSize(final ClassWriter cw, final byte[] code, final int len, |
||||
final int maxStack, final int maxLocals) { |
||||
Attribute attr = this; |
||||
int size = 0; |
||||
while (attr != null) { |
||||
cw.newUTF8(attr.type); |
||||
size += attr.write(cw, code, len, maxStack, maxLocals).length + 6; |
||||
attr = attr.next; |
||||
} |
||||
return size; |
||||
} |
||||
|
||||
/** |
||||
* Writes all the attributes of this attribute list in the given byte |
||||
* vector. |
||||
* |
||||
* @param cw |
||||
* the class writer to be used to convert the attributes into |
||||
* byte arrays, with the {@link #write write} method. |
||||
* @param code |
||||
* the bytecode of the method corresponding to these code |
||||
* attributes, or <tt>null</tt> if these attributes are not code |
||||
* attributes. |
||||
* @param len |
||||
* the length of the bytecode of the method corresponding to |
||||
* these code attributes, or <tt>null</tt> if these attributes |
||||
* are not code attributes. |
||||
* @param maxStack |
||||
* the maximum stack size of the method corresponding to these |
||||
* code attributes, or -1 if these attributes are not code |
||||
* attributes. |
||||
* @param maxLocals |
||||
* the maximum number of local variables of the method |
||||
* corresponding to these code attributes, or -1 if these |
||||
* attributes are not code attributes. |
||||
* @param out |
||||
* where the attributes must be written. |
||||
*/ |
||||
final void put(final ClassWriter cw, final byte[] code, final int len, |
||||
final int maxStack, final int maxLocals, final ByteVector out) { |
||||
Attribute attr = this; |
||||
while (attr != null) { |
||||
ByteVector b = attr.write(cw, code, len, maxStack, maxLocals); |
||||
out.putShort(cw.newUTF8(attr.type)).putInt(b.length); |
||||
out.putByteArray(b.data, 0, b.length); |
||||
attr = attr.next; |
||||
} |
||||
} |
||||
} |
@ -1,339 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* A dynamically extensible vector of bytes. This class is roughly equivalent to |
||||
* a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient. |
||||
* |
||||
* @author Eric Bruneton |
||||
*/ |
||||
public class ByteVector { |
||||
|
||||
/** |
||||
* The content of this vector. |
||||
*/ |
||||
byte[] data; |
||||
|
||||
/** |
||||
* Actual number of bytes in this vector. |
||||
*/ |
||||
int length; |
||||
|
||||
/** |
||||
* Constructs a new {@link ByteVector ByteVector} with a default initial |
||||
* size. |
||||
*/ |
||||
public ByteVector() { |
||||
data = new byte[64]; |
||||
} |
||||
|
||||
/** |
||||
* Constructs a new {@link ByteVector ByteVector} with the given initial |
||||
* size. |
||||
* |
||||
* @param initialSize |
||||
* the initial size of the byte vector to be constructed. |
||||
*/ |
||||
public ByteVector(final int initialSize) { |
||||
data = new byte[initialSize]; |
||||
} |
||||
|
||||
/** |
||||
* Puts a byte into this byte vector. The byte vector is automatically |
||||
* enlarged if necessary. |
||||
* |
||||
* @param b |
||||
* a byte. |
||||
* @return this byte vector. |
||||
*/ |
||||
public ByteVector putByte(final int b) { |
||||
int length = this.length; |
||||
if (length + 1 > data.length) { |
||||
enlarge(1); |
||||
} |
||||
data[length++] = (byte) b; |
||||
this.length = length; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Puts two bytes into this byte vector. The byte vector is automatically |
||||
* enlarged if necessary. |
||||
* |
||||
* @param b1 |
||||
* a byte. |
||||
* @param b2 |
||||
* another byte. |
||||
* @return this byte vector. |
||||
*/ |
||||
ByteVector put11(final int b1, final int b2) { |
||||
int length = this.length; |
||||
if (length + 2 > data.length) { |
||||
enlarge(2); |
||||
} |
||||
byte[] data = this.data; |
||||
data[length++] = (byte) b1; |
||||
data[length++] = (byte) b2; |
||||
this.length = length; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Puts a short into this byte vector. The byte vector is automatically |
||||
* enlarged if necessary. |
||||
* |
||||
* @param s |
||||
* a short. |
||||
* @return this byte vector. |
||||
*/ |
||||
public ByteVector putShort(final int s) { |
||||
int length = this.length; |
||||
if (length + 2 > data.length) { |
||||
enlarge(2); |
||||
} |
||||
byte[] data = this.data; |
||||
data[length++] = (byte) (s >>> 8); |
||||
data[length++] = (byte) s; |
||||
this.length = length; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Puts a byte and a short into this byte vector. The byte vector is |
||||
* automatically enlarged if necessary. |
||||
* |
||||
* @param b |
||||
* a byte. |
||||
* @param s |
||||
* a short. |
||||
* @return this byte vector. |
||||
*/ |
||||
ByteVector put12(final int b, final int s) { |
||||
int length = this.length; |
||||
if (length + 3 > data.length) { |
||||
enlarge(3); |
||||
} |
||||
byte[] data = this.data; |
||||
data[length++] = (byte) b; |
||||
data[length++] = (byte) (s >>> 8); |
||||
data[length++] = (byte) s; |
||||
this.length = length; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Puts an int into this byte vector. The byte vector is automatically |
||||
* enlarged if necessary. |
||||
* |
||||
* @param i |
||||
* an int. |
||||
* @return this byte vector. |
||||
*/ |
||||
public ByteVector putInt(final int i) { |
||||
int length = this.length; |
||||
if (length + 4 > data.length) { |
||||
enlarge(4); |
||||
} |
||||
byte[] data = this.data; |
||||
data[length++] = (byte) (i >>> 24); |
||||
data[length++] = (byte) (i >>> 16); |
||||
data[length++] = (byte) (i >>> 8); |
||||
data[length++] = (byte) i; |
||||
this.length = length; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Puts a long into this byte vector. The byte vector is automatically |
||||
* enlarged if necessary. |
||||
* |
||||
* @param l |
||||
* a long. |
||||
* @return this byte vector. |
||||
*/ |
||||
public ByteVector putLong(final long l) { |
||||
int length = this.length; |
||||
if (length + 8 > data.length) { |
||||
enlarge(8); |
||||
} |
||||
byte[] data = this.data; |
||||
int i = (int) (l >>> 32); |
||||
data[length++] = (byte) (i >>> 24); |
||||
data[length++] = (byte) (i >>> 16); |
||||
data[length++] = (byte) (i >>> 8); |
||||
data[length++] = (byte) i; |
||||
i = (int) l; |
||||
data[length++] = (byte) (i >>> 24); |
||||
data[length++] = (byte) (i >>> 16); |
||||
data[length++] = (byte) (i >>> 8); |
||||
data[length++] = (byte) i; |
||||
this.length = length; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Puts an UTF8 string into this byte vector. The byte vector is |
||||
* automatically enlarged if necessary. |
||||
* |
||||
* @param s |
||||
* a String whose UTF8 encoded length must be less than 65536. |
||||
* @return this byte vector. |
||||
*/ |
||||
public ByteVector putUTF8(final String s) { |
||||
int charLength = s.length(); |
||||
if (charLength > 65535) { |
||||
throw new IllegalArgumentException(); |
||||
} |
||||
int len = length; |
||||
if (len + 2 + charLength > data.length) { |
||||
enlarge(2 + charLength); |
||||
} |
||||
byte[] data = this.data; |
||||
// optimistic algorithm: instead of computing the byte length and then
|
||||
// serializing the string (which requires two loops), we assume the byte
|
||||
// length is equal to char length (which is the most frequent case), and
|
||||
// we start serializing the string right away. During the serialization,
|
||||
// if we find that this assumption is wrong, we continue with the
|
||||
// general method.
|
||||
data[len++] = (byte) (charLength >>> 8); |
||||
data[len++] = (byte) charLength; |
||||
for (int i = 0; i < charLength; ++i) { |
||||
char c = s.charAt(i); |
||||
if (c >= '\001' && c <= '\177') { |
||||
data[len++] = (byte) c; |
||||
} else { |
||||
length = len; |
||||
return encodeUTF8(s, i, 65535); |
||||
} |
||||
} |
||||
length = len; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Puts an UTF8 string into this byte vector. The byte vector is |
||||
* automatically enlarged if necessary. The string length is encoded in two |
||||
* bytes before the encoded characters, if there is space for that (i.e. if |
||||
* this.length - i - 2 >= 0). |
||||
* |
||||
* @param s |
||||
* the String to encode. |
||||
* @param i |
||||
* the index of the first character to encode. The previous |
||||
* characters are supposed to have already been encoded, using |
||||
* only one byte per character. |
||||
* @param maxByteLength |
||||
* the maximum byte length of the encoded string, including the |
||||
* already encoded characters. |
||||
* @return this byte vector. |
||||
*/ |
||||
ByteVector encodeUTF8(final String s, int i, int maxByteLength) { |
||||
int charLength = s.length(); |
||||
int byteLength = i; |
||||
char c; |
||||
for (int j = i; j < charLength; ++j) { |
||||
c = s.charAt(j); |
||||
if (c >= '\001' && c <= '\177') { |
||||
byteLength++; |
||||
} else if (c > '\u07FF') { |
||||
byteLength += 3; |
||||
} else { |
||||
byteLength += 2; |
||||
} |
||||
} |
||||
if (byteLength > maxByteLength) { |
||||
throw new IllegalArgumentException(); |
||||
} |
||||
int start = length - i - 2; |
||||
if (start >= 0) { |
||||
data[start] = (byte) (byteLength >>> 8); |
||||
data[start + 1] = (byte) byteLength; |
||||
} |
||||
if (length + byteLength - i > data.length) { |
||||
enlarge(byteLength - i); |
||||
} |
||||
int len = length; |
||||
for (int j = i; j < charLength; ++j) { |
||||
c = s.charAt(j); |
||||
if (c >= '\001' && c <= '\177') { |
||||
data[len++] = (byte) c; |
||||
} else if (c > '\u07FF') { |
||||
data[len++] = (byte) (0xE0 | c >> 12 & 0xF); |
||||
data[len++] = (byte) (0x80 | c >> 6 & 0x3F); |
||||
data[len++] = (byte) (0x80 | c & 0x3F); |
||||
} else { |
||||
data[len++] = (byte) (0xC0 | c >> 6 & 0x1F); |
||||
data[len++] = (byte) (0x80 | c & 0x3F); |
||||
} |
||||
} |
||||
length = len; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Puts an array of bytes into this byte vector. The byte vector is |
||||
* automatically enlarged if necessary. |
||||
* |
||||
* @param b |
||||
* an array of bytes. May be <tt>null</tt> to put <tt>len</tt> |
||||
* null bytes into this byte vector. |
||||
* @param off |
||||
* index of the fist byte of b that must be copied. |
||||
* @param len |
||||
* number of bytes of b that must be copied. |
||||
* @return this byte vector. |
||||
*/ |
||||
public ByteVector putByteArray(final byte[] b, final int off, final int len) { |
||||
if (length + len > data.length) { |
||||
enlarge(len); |
||||
} |
||||
if (b != null) { |
||||
System.arraycopy(b, off, data, length, len); |
||||
} |
||||
length += len; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Enlarge this byte vector so that it can receive n more bytes. |
||||
* |
||||
* @param size |
||||
* number of additional bytes that this byte vector should be |
||||
* able to receive. |
||||
*/ |
||||
private void enlarge(final int size) { |
||||
int length1 = 2 * data.length; |
||||
int length2 = length + size; |
||||
byte[] newData = new byte[length1 > length2 ? length1 : length2]; |
||||
System.arraycopy(data, 0, newData, 0, length); |
||||
data = newData; |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,342 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* 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> ] [ |
||||
* <tt>visitModule</tt> ][ <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> | |
||||
* <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* ( |
||||
* <tt>visitInnerClass</tt> | <tt>visitField</tt> | <tt>visitMethod</tt> )* |
||||
* <tt>visitEnd</tt>. |
||||
* |
||||
* @author Eric Bruneton |
||||
*/ |
||||
public abstract class ClassVisitor { |
||||
|
||||
/** |
||||
* The ASM API version implemented by this visitor. The value of this field |
||||
* must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. |
||||
*/ |
||||
protected final int api; |
||||
|
||||
/** |
||||
* The class visitor to which this visitor must delegate method calls. May |
||||
* be null. |
||||
*/ |
||||
protected ClassVisitor cv; |
||||
|
||||
/** |
||||
* Constructs a new {@link ClassVisitor}. |
||||
* |
||||
* @param api |
||||
* the ASM API version implemented by this visitor. Must be one |
||||
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. |
||||
*/ |
||||
public ClassVisitor(final int api) { |
||||
this(api, null); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a new {@link ClassVisitor}. |
||||
* |
||||
* @param api |
||||
* the ASM API version implemented by this visitor. Must be one |
||||
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. |
||||
* @param cv |
||||
* the class visitor to which this visitor must delegate method |
||||
* calls. May be null. |
||||
*/ |
||||
public ClassVisitor(final int api, final ClassVisitor cv) { |
||||
if (api < Opcodes.ASM4 || api > Opcodes.ASM6) { |
||||
throw new IllegalArgumentException(); |
||||
} |
||||
this.api = api; |
||||
this.cv = cv; |
||||
} |
||||
|
||||
/** |
||||
* Visits the header of the class. |
||||
* |
||||
* @param version |
||||
* the class version. |
||||
* @param access |
||||
* the class's access flags (see {@link Opcodes}). This parameter |
||||
* also indicates if the class is deprecated. |
||||
* @param name |
||||
* the internal name of the class (see |
||||
* {@link Type#getInternalName() getInternalName}). |
||||
* @param signature |
||||
* the signature of this class. May be <tt>null</tt> if the class
|
||||
* is not a generic one, and does not extend or implement generic |
||||
* classes or interfaces. |
||||
* @param superName |
||||
* the internal of name of the super class (see |
||||
* {@link Type#getInternalName() getInternalName}). For |
||||
* interfaces, the super class is {@link Object}. May be |
||||
* <tt>null</tt>, but only for the {@link Object} class. |
||||
* @param interfaces |
||||
* the internal names of the class's interfaces (see |
||||
* {@link Type#getInternalName() getInternalName}). May be |
||||
* <tt>null</tt>. |
||||
*/ |
||||
public void visit(int version, int access, String name, String signature, |
||||
String superName, String[] interfaces) { |
||||
if (cv != null) { |
||||
cv.visit(version, access, name, signature, superName, interfaces); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits the source of the class. |
||||
* |
||||
* @param source |
||||
* the name of the source file from which the class was compiled. |
||||
* May be <tt>null</tt>. |
||||
* @param debug |
||||
* additional debug information to compute the correspondance |
||||
* between source and compiled elements of the class. May be |
||||
* <tt>null</tt>. |
||||
*/ |
||||
public void visitSource(String source, String debug) { |
||||
if (cv != null) { |
||||
cv.visitSource(source, debug); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visit the module corresponding to the class. |
||||
* @param name |
||||
* module name |
||||
* @param access |
||||
* module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} |
||||
* and {@code ACC_MANDATED}. |
||||
* @param version |
||||
* module version or null. |
||||
* @return a visitor to visit the module values, or <tt>null</tt> if |
||||
* this visitor is not interested in visiting this module. |
||||
*/ |
||||
public ModuleVisitor visitModule(String name, int access, String version) { |
||||
if (api < Opcodes.ASM6) { |
||||
throw new RuntimeException(); |
||||
} |
||||
if (cv != null) { |
||||
return cv.visitModule(name, access, version); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Visits the enclosing class of the class. This method must be called only |
||||
* if the class has an enclosing class. |
||||
* |
||||
* @param owner |
||||
* internal name of the enclosing class of the class. |
||||
* @param name |
||||
* the name of the method that contains the class, or |
||||
* <tt>null</tt> if the class is not enclosed in a method of its |
||||
* enclosing class. |
||||
* @param desc |
||||
* the descriptor of the method that contains the class, or |
||||
* <tt>null</tt> if the class is not enclosed in a method of its |
||||
* enclosing class. |
||||
*/ |
||||
public void visitOuterClass(String owner, String name, String desc) { |
||||
if (cv != null) { |
||||
cv.visitOuterClass(owner, name, desc); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits an annotation of the class. |
||||
* |
||||
* @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 visitAnnotation(String desc, boolean visible) { |
||||
if (cv != null) { |
||||
return cv.visitAnnotation(desc, visible); |
||||
} |
||||
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. |
||||
* |
||||
* @param attr |
||||
* an attribute. |
||||
*/ |
||||
public void visitAttribute(Attribute attr) { |
||||
if (cv != null) { |
||||
cv.visitAttribute(attr); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits information about an inner class. This inner class is not |
||||
* necessarily a member of the class being visited. |
||||
* |
||||
* @param name |
||||
* the internal name of an inner class (see |
||||
* {@link Type#getInternalName() getInternalName}). |
||||
* @param outerName |
||||
* the internal name of the class to which the inner class
|
||||
* belongs (see {@link Type#getInternalName() getInternalName}). |
||||
* May be <tt>null</tt> for not member classes. |
||||
* @param innerName |
||||
* the (simple) name of the inner class inside its enclosing |
||||
* class. May be <tt>null</tt> for anonymous inner classes. |
||||
* @param access |
||||
* the access flags of the inner class as originally declared in |
||||
* the enclosing class. |
||||
*/ |
||||
public void visitInnerClass(String name, String outerName, |
||||
String innerName, int access) { |
||||
if (cv != null) { |
||||
cv.visitInnerClass(name, outerName, innerName, access); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits a field of the class. |
||||
* |
||||
* @param access |
||||
* the field's access flags (see {@link Opcodes}). This parameter |
||||
* also indicates if the field is synthetic and/or deprecated. |
||||
* @param name |
||||
* the field's name. |
||||
* @param desc |
||||
* the field's descriptor (see {@link Type Type}). |
||||
* @param signature |
||||
* the field's signature. May be <tt>null</tt> if the field's |
||||
* type does not use generic types. |
||||
* @param value |
||||
* the field's initial value. This parameter, which may be |
||||
* <tt>null</tt> if the field does not have an initial value, |
||||
* must be an {@link Integer}, a {@link Float}, a {@link Long}, a |
||||
* {@link Double} or a {@link String} (for <tt>int</tt>, |
||||
* <tt>float</tt>, <tt>long</tt> or <tt>String</tt> fields |
||||
* respectively). <i>This parameter is only used for static |
||||
* fields</i>. Its value is ignored for non static fields, which |
||||
* must be initialized through bytecode instructions in |
||||
* constructors or methods. |
||||
* @return a visitor to visit field annotations and attributes, or |
||||
* <tt>null</tt> if this class visitor is not interested in visiting |
||||
* these annotations and attributes. |
||||
*/ |
||||
public FieldVisitor visitField(int access, String name, String desc, |
||||
String signature, Object value) { |
||||
if (cv != null) { |
||||
return cv.visitField(access, name, desc, signature, value); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Visits a method of the class. This method <i>must</i> return a new |
||||
* {@link MethodVisitor} instance (or <tt>null</tt>) each time it is called, |
||||
* i.e., it should not return a previously returned visitor. |
||||
* |
||||
* @param access |
||||
* the method's access flags (see {@link Opcodes}). This |
||||
* parameter also indicates if the method is synthetic and/or |
||||
* deprecated. |
||||
* @param name |
||||
* the method's name. |
||||
* @param desc |
||||
* the method's descriptor (see {@link Type Type}). |
||||
* @param signature |
||||
* the method's signature. May be <tt>null</tt> if the method |
||||
* parameters, return type and exceptions do not use generic |
||||
* types. |
||||
* @param exceptions |
||||
* the internal names of the method's exception classes (see |
||||
* {@link Type#getInternalName() getInternalName}). May be |
||||
* <tt>null</tt>. |
||||
* @return an object to visit the byte code of the method, or <tt>null</tt> |
||||
* if this class visitor is not interested in visiting the code of |
||||
* this method. |
||||
*/ |
||||
public MethodVisitor visitMethod(int access, String name, String desc, |
||||
String signature, String[] exceptions) { |
||||
if (cv != null) { |
||||
return cv.visitMethod(access, name, desc, signature, exceptions); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Visits the end of the class. This method, which is the last one to be |
||||
* called, is used to inform the visitor that all the fields and methods of |
||||
* the class have been visited. |
||||
*/ |
||||
public void visitEnd() { |
||||
if (cv != null) { |
||||
cv.visitEnd(); |
||||
} |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,145 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* Information about a class being parsed in a {@link ClassReader}. |
||||
* |
||||
* @author Eric Bruneton |
||||
*/ |
||||
class Context { |
||||
|
||||
/** |
||||
* Prototypes of the attributes that must be parsed for this class. |
||||
*/ |
||||
Attribute[] attrs; |
||||
|
||||
/** |
||||
* The {@link ClassReader} option flags for the parsing of this class. |
||||
*/ |
||||
int flags; |
||||
|
||||
/** |
||||
* The buffer used to read strings. |
||||
*/ |
||||
char[] buffer; |
||||
|
||||
/** |
||||
* The start index of each bootstrap method. |
||||
*/ |
||||
int[] bootstrapMethods; |
||||
|
||||
/** |
||||
* The access flags of the method currently being parsed. |
||||
*/ |
||||
int access; |
||||
|
||||
/** |
||||
* The name of the method currently being parsed. |
||||
*/ |
||||
String name; |
||||
|
||||
/** |
||||
* The descriptor of the method currently being parsed. |
||||
*/ |
||||
String desc; |
||||
|
||||
/** |
||||
* The label objects, indexed by bytecode offset, of the method currently |
||||
* being parsed (only bytecode offsets for which a label is needed have a |
||||
* non null associated Label object). |
||||
*/ |
||||
Label[] labels; |
||||
|
||||
/** |
||||
* The target of the type annotation currently being parsed. |
||||
*/ |
||||
int typeRef; |
||||
|
||||
/** |
||||
* The path of the type annotation currently being parsed. |
||||
*/ |
||||
TypePath typePath; |
||||
|
||||
/** |
||||
* The offset of the latest stack map frame that has been parsed. |
||||
*/ |
||||
int offset; |
||||
|
||||
/** |
||||
* The labels corresponding to the start of the local variable ranges in the |
||||
* local variable type annotation currently being parsed. |
||||
*/ |
||||
Label[] start; |
||||
|
||||
/** |
||||
* The labels corresponding to the end of the local variable ranges in the |
||||
* local variable type annotation currently being parsed. |
||||
*/ |
||||
Label[] end; |
||||
|
||||
/** |
||||
* The local variable indices for each local variable range in the local |
||||
* variable type annotation currently being parsed. |
||||
*/ |
||||
int[] index; |
||||
|
||||
/** |
||||
* The encoding of the latest stack map frame that has been parsed. |
||||
*/ |
||||
int mode; |
||||
|
||||
/** |
||||
* The number of locals in the latest stack map frame that has been parsed. |
||||
*/ |
||||
int localCount; |
||||
|
||||
/** |
||||
* The number locals in the latest stack map frame that has been parsed, |
||||
* minus the number of locals in the previous frame. |
||||
*/ |
||||
int localDiff; |
||||
|
||||
/** |
||||
* The local values of the latest stack map frame that has been parsed. |
||||
*/ |
||||
Object[] local; |
||||
|
||||
/** |
||||
* The stack size of the latest stack map frame that has been parsed. |
||||
*/ |
||||
int stackCount; |
||||
|
||||
/** |
||||
* The stack values of the latest stack map frame that has been parsed. |
||||
*/ |
||||
Object[] stack; |
||||
} |
@ -1,56 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* Information about the input stack map frame at the "current" instruction of a |
||||
* method. This is implemented as a Frame subclass for a "basic block" |
||||
* containing only one instruction. |
||||
* |
||||
* @author Eric Bruneton |
||||
*/ |
||||
class CurrentFrame extends Frame { |
||||
|
||||
/** |
||||
* Sets this CurrentFrame to the input stack map frame of the next "current" |
||||
* instruction, i.e. the instruction just after the given one. It is assumed |
||||
* that the value of this object when this method is called is the stack map |
||||
* frame status just before the given instruction is executed. |
||||
*/ |
||||
@Override |
||||
void execute(int opcode, int arg, ClassWriter cw, Item item) { |
||||
super.execute(opcode, arg, cw, item); |
||||
Frame successor = new Frame(); |
||||
merge(cw, successor, 0); |
||||
set(successor); |
||||
owner.inputStackTop = 0; |
||||
} |
||||
} |
@ -1,75 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* An edge in the control flow graph of a method body. See {@link Label Label}. |
||||
* |
||||
* @author Eric Bruneton |
||||
*/ |
||||
class Edge { |
||||
|
||||
/** |
||||
* Denotes a normal control flow graph edge. |
||||
*/ |
||||
static final int NORMAL = 0; |
||||
|
||||
/** |
||||
* Denotes a control flow graph edge corresponding to an exception handler. |
||||
* More precisely any {@link Edge} whose {@link #info} is strictly positive |
||||
* corresponds to an exception handler. The actual value of {@link #info} is |
||||
* the index, in the {@link ClassWriter} type table, of the exception that |
||||
* is catched. |
||||
*/ |
||||
static final int EXCEPTION = 0x7FFFFFFF; |
||||
|
||||
/** |
||||
* Information about this control flow graph edge. If |
||||
* {@link ClassWriter#COMPUTE_MAXS} is used this field is the (relative) |
||||
* stack size in the basic block from which this edge originates. This size |
||||
* is equal to the stack size at the "jump" instruction to which this edge |
||||
* corresponds, relatively to the stack size at the beginning of the |
||||
* originating basic block. If {@link ClassWriter#COMPUTE_FRAMES} is used, |
||||
* this field is the kind of this control flow graph edge (i.e. NORMAL or |
||||
* EXCEPTION). |
||||
*/ |
||||
int info; |
||||
|
||||
/** |
||||
* The successor block of the basic block from which this edge originates. |
||||
*/ |
||||
Label successor; |
||||
|
||||
/** |
||||
* The next edge in the list of successors of the originating basic block. |
||||
* See {@link Label#successors successors}. |
||||
*/ |
||||
Edge next; |
||||
} |
@ -1,150 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* A visitor to visit a Java field. The methods of this class must be called in |
||||
* the following order: ( <tt>visitAnnotation</tt> | |
||||
* <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* <tt>visitEnd</tt>. |
||||
* |
||||
* @author Eric Bruneton |
||||
*/ |
||||
public abstract class FieldVisitor { |
||||
|
||||
/** |
||||
* The ASM API version implemented by this visitor. The value of this field |
||||
* must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. |
||||
*/ |
||||
protected final int api; |
||||
|
||||
/** |
||||
* The field visitor to which this visitor must delegate method calls. May |
||||
* be null. |
||||
*/ |
||||
protected FieldVisitor fv; |
||||
|
||||
/** |
||||
* Constructs a new {@link FieldVisitor}. |
||||
* |
||||
* @param api |
||||
* the ASM API version implemented by this visitor. Must be one |
||||
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. |
||||
*/ |
||||
public FieldVisitor(final int api) { |
||||
this(api, null); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a new {@link FieldVisitor}. |
||||
* |
||||
* @param api |
||||
* the ASM API version implemented by this visitor. Must be one |
||||
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. |
||||
* @param fv |
||||
* the field visitor to which this visitor must delegate method |
||||
* calls. May be null. |
||||
*/ |
||||
public FieldVisitor(final int api, final FieldVisitor fv) { |
||||
if (api < Opcodes.ASM4 || api > Opcodes.ASM6) { |
||||
throw new IllegalArgumentException(); |
||||
} |
||||
this.api = api; |
||||
this.fv = fv; |
||||
} |
||||
|
||||
/** |
||||
* Visits an annotation of the field. |
||||
* |
||||
* @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 visitAnnotation(String desc, boolean visible) { |
||||
if (fv != null) { |
||||
return fv.visitAnnotation(desc, visible); |
||||
} |
||||
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. |
||||
* |
||||
* @param attr |
||||
* an attribute. |
||||
*/ |
||||
public void visitAttribute(Attribute attr) { |
||||
if (fv != null) { |
||||
fv.visitAttribute(attr); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits the end of the field. This method, which is the last one to be |
||||
* called, is used to inform the visitor that all the annotations and |
||||
* attributes of the field have been visited. |
||||
*/ |
||||
public void visitEnd() { |
||||
if (fv != null) { |
||||
fv.visitEnd(); |
||||
} |
||||
} |
||||
} |
@ -1,323 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* An {@link FieldVisitor} that generates Java fields in bytecode form. |
||||
* |
||||
* @author Eric Bruneton |
||||
*/ |
||||
final class FieldWriter extends FieldVisitor { |
||||
|
||||
/** |
||||
* The class writer to which this field must be added. |
||||
*/ |
||||
private final ClassWriter cw; |
||||
|
||||
/** |
||||
* Access flags of this field. |
||||
*/ |
||||
private final int access; |
||||
|
||||
/** |
||||
* The index of the constant pool item that contains the name of this |
||||
* method. |
||||
*/ |
||||
private final int name; |
||||
|
||||
/** |
||||
* The index of the constant pool item that contains the descriptor of this |
||||
* field. |
||||
*/ |
||||
private final int desc; |
||||
|
||||
/** |
||||
* The index of the constant pool item that contains the signature of this |
||||
* field. |
||||
*/ |
||||
private int signature; |
||||
|
||||
/** |
||||
* The index of the constant pool item that contains the constant value of |
||||
* this field. |
||||
*/ |
||||
private int value; |
||||
|
||||
/** |
||||
* The runtime visible annotations of this field. May be <tt>null</tt>. |
||||
*/ |
||||
private AnnotationWriter anns; |
||||
|
||||
/** |
||||
* The runtime invisible annotations of this field. May be <tt>null</tt>. |
||||
*/ |
||||
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>. |
||||
*/ |
||||
private Attribute attrs; |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Constructs a new {@link FieldWriter}. |
||||
* |
||||
* @param cw |
||||
* the class writer to which this field must be added. |
||||
* @param access |
||||
* the field's access flags (see {@link Opcodes}). |
||||
* @param name |
||||
* the field's name. |
||||
* @param desc |
||||
* the field's descriptor (see {@link Type}). |
||||
* @param signature |
||||
* the field's signature. May be <tt>null</tt>. |
||||
* @param value |
||||
* the field's constant value. May be <tt>null</tt>. |
||||
*/ |
||||
FieldWriter(final ClassWriter cw, final int access, final String name, |
||||
final String desc, final String signature, final Object value) { |
||||
super(Opcodes.ASM6); |
||||
if (cw.firstField == null) { |
||||
cw.firstField = this; |
||||
} else { |
||||
cw.lastField.fv = this; |
||||
} |
||||
cw.lastField = this; |
||||
this.cw = cw; |
||||
this.access = access; |
||||
this.name = cw.newUTF8(name); |
||||
this.desc = cw.newUTF8(desc); |
||||
if (signature != null) { |
||||
this.signature = cw.newUTF8(signature); |
||||
} |
||||
if (value != null) { |
||||
this.value = cw.newConstItem(value).index; |
||||
} |
||||
} |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Implementation of the FieldVisitor abstract class
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@Override |
||||
public AnnotationVisitor visitAnnotation(final String desc, |
||||
final boolean visible) { |
||||
ByteVector bv = new ByteVector(); |
||||
// write type, and reserve space for values count
|
||||
bv.putShort(cw.newUTF8(desc)).putShort(0); |
||||
AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); |
||||
if (visible) { |
||||
aw.next = anns; |
||||
anns = aw; |
||||
} else { |
||||
aw.next = ianns; |
||||
ianns = aw; |
||||
} |
||||
return aw; |
||||
} |
||||
|
||||
@Override |
||||
public AnnotationVisitor visitTypeAnnotation(final int typeRef, |
||||
final TypePath typePath, final String desc, final boolean visible) { |
||||
ByteVector bv = new ByteVector(); |
||||
// write target_type and target_info
|
||||
AnnotationWriter.putTarget(typeRef, typePath, bv); |
||||
// write type, and reserve space for values count
|
||||
bv.putShort(cw.newUTF8(desc)).putShort(0); |
||||
AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, |
||||
bv.length - 2); |
||||
if (visible) { |
||||
aw.next = tanns; |
||||
tanns = aw; |
||||
} else { |
||||
aw.next = itanns; |
||||
itanns = aw; |
||||
} |
||||
return aw; |
||||
} |
||||
|
||||
@Override |
||||
public void visitAttribute(final Attribute attr) { |
||||
attr.next = attrs; |
||||
attrs = attr; |
||||
} |
||||
|
||||
@Override |
||||
public void visitEnd() { |
||||
} |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Utility methods
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Returns the size of this field. |
||||
* |
||||
* @return the size of this field. |
||||
*/ |
||||
int getSize() { |
||||
int size = 8; |
||||
if (value != 0) { |
||||
cw.newUTF8("ConstantValue"); |
||||
size += 8; |
||||
} |
||||
if ((access & Opcodes.ACC_SYNTHETIC) != 0) { |
||||
if ((cw.version & 0xFFFF) < Opcodes.V1_5 |
||||
|| (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { |
||||
cw.newUTF8("Synthetic"); |
||||
size += 6; |
||||
} |
||||
} |
||||
if ((access & Opcodes.ACC_DEPRECATED) != 0) { |
||||
cw.newUTF8("Deprecated"); |
||||
size += 6; |
||||
} |
||||
if (signature != 0) { |
||||
cw.newUTF8("Signature"); |
||||
size += 8; |
||||
} |
||||
if (anns != null) { |
||||
cw.newUTF8("RuntimeVisibleAnnotations"); |
||||
size += 8 + anns.getSize(); |
||||
} |
||||
if (ianns != null) { |
||||
cw.newUTF8("RuntimeInvisibleAnnotations"); |
||||
size += 8 + ianns.getSize(); |
||||
} |
||||
if (tanns != null) { |
||||
cw.newUTF8("RuntimeVisibleTypeAnnotations"); |
||||
size += 8 + tanns.getSize(); |
||||
} |
||||
if (itanns != null) { |
||||
cw.newUTF8("RuntimeInvisibleTypeAnnotations"); |
||||
size += 8 + itanns.getSize(); |
||||
} |
||||
if (attrs != null) { |
||||
size += attrs.getSize(cw, null, 0, -1, -1); |
||||
} |
||||
return size; |
||||
} |
||||
|
||||
/** |
||||
* Puts the content of this field into the given byte vector. |
||||
* |
||||
* @param out |
||||
* where the content of this field must be put. |
||||
*/ |
||||
void put(final ByteVector out) { |
||||
final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC; |
||||
int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE |
||||
| ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR); |
||||
out.putShort(access & ~mask).putShort(name).putShort(desc); |
||||
int attributeCount = 0; |
||||
if (value != 0) { |
||||
++attributeCount; |
||||
} |
||||
if ((access & Opcodes.ACC_SYNTHETIC) != 0) { |
||||
if ((cw.version & 0xFFFF) < Opcodes.V1_5 |
||||
|| (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { |
||||
++attributeCount; |
||||
} |
||||
} |
||||
if ((access & Opcodes.ACC_DEPRECATED) != 0) { |
||||
++attributeCount; |
||||
} |
||||
if (signature != 0) { |
||||
++attributeCount; |
||||
} |
||||
if (anns != null) { |
||||
++attributeCount; |
||||
} |
||||
if (ianns != null) { |
||||
++attributeCount; |
||||
} |
||||
if (tanns != null) { |
||||
++attributeCount; |
||||
} |
||||
if (itanns != null) { |
||||
++attributeCount; |
||||
} |
||||
if (attrs != null) { |
||||
attributeCount += attrs.getCount(); |
||||
} |
||||
out.putShort(attributeCount); |
||||
if (value != 0) { |
||||
out.putShort(cw.newUTF8("ConstantValue")); |
||||
out.putInt(2).putShort(value); |
||||
} |
||||
if ((access & Opcodes.ACC_SYNTHETIC) != 0) { |
||||
if ((cw.version & 0xFFFF) < Opcodes.V1_5 |
||||
|| (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { |
||||
out.putShort(cw.newUTF8("Synthetic")).putInt(0); |
||||
} |
||||
} |
||||
if ((access & Opcodes.ACC_DEPRECATED) != 0) { |
||||
out.putShort(cw.newUTF8("Deprecated")).putInt(0); |
||||
} |
||||
if (signature != 0) { |
||||
out.putShort(cw.newUTF8("Signature")); |
||||
out.putInt(2).putShort(signature); |
||||
} |
||||
if (anns != null) { |
||||
out.putShort(cw.newUTF8("RuntimeVisibleAnnotations")); |
||||
anns.put(out); |
||||
} |
||||
if (ianns != null) { |
||||
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations")); |
||||
ianns.put(out); |
||||
} |
||||
if (tanns != null) { |
||||
out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations")); |
||||
tanns.put(out); |
||||
} |
||||
if (itanns != null) { |
||||
out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations")); |
||||
itanns.put(out); |
||||
} |
||||
if (attrs != null) { |
||||
attrs.put(cw, null, 0, -1, -1, out); |
||||
} |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,222 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* A reference to a field or a method. |
||||
* |
||||
* @author Remi Forax |
||||
* @author Eric Bruneton |
||||
*/ |
||||
public final class Handle { |
||||
|
||||
/** |
||||
* The kind of field or method designated by this Handle. Should be |
||||
* {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, |
||||
* {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, |
||||
* {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, |
||||
* {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or |
||||
* {@link Opcodes#H_INVOKEINTERFACE}. |
||||
*/ |
||||
final int tag; |
||||
|
||||
/** |
||||
* The internal name of the class that owns the field or method designated |
||||
* by this handle. |
||||
*/ |
||||
final String owner; |
||||
|
||||
/** |
||||
* The name of the field or method designated by this handle. |
||||
*/ |
||||
final String name; |
||||
|
||||
/** |
||||
* The descriptor of the field or method designated by this handle. |
||||
*/ |
||||
final String desc; |
||||
|
||||
|
||||
/** |
||||
* Indicate if the owner is an interface or not. |
||||
*/ |
||||
final boolean itf; |
||||
|
||||
/** |
||||
* Constructs a new field or method handle. |
||||
* |
||||
* @param tag |
||||
* the kind of field or method designated by this Handle. Must be |
||||
* {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, |
||||
* {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, |
||||
* {@link Opcodes#H_INVOKEVIRTUAL}, |
||||
* {@link Opcodes#H_INVOKESTATIC}, |
||||
* {@link Opcodes#H_INVOKESPECIAL}, |
||||
* {@link Opcodes#H_NEWINVOKESPECIAL} or |
||||
* {@link Opcodes#H_INVOKEINTERFACE}. |
||||
* @param owner |
||||
* the internal name of the class that owns the field or method |
||||
* designated by this handle. |
||||
* @param name |
||||
* the name of the field or method designated by this handle. |
||||
* @param desc |
||||
* the descriptor of the field or method designated by this |
||||
* handle. |
||||
* |
||||
* @deprecated this constructor has been superseded |
||||
* by {@link #Handle(int, String, String, String, boolean)}. |
||||
*/ |
||||
@Deprecated |
||||
public Handle(int tag, String owner, String name, String desc) { |
||||
this(tag, owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a new field or method handle. |
||||
* |
||||
* @param tag |
||||
* the kind of field or method designated by this Handle. Must be |
||||
* {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, |
||||
* {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, |
||||
* {@link Opcodes#H_INVOKEVIRTUAL}, |
||||
* {@link Opcodes#H_INVOKESTATIC}, |
||||
* {@link Opcodes#H_INVOKESPECIAL}, |
||||
* {@link Opcodes#H_NEWINVOKESPECIAL} or |
||||
* {@link Opcodes#H_INVOKEINTERFACE}. |
||||
* @param owner |
||||
* the internal name of the class that owns the field or method |
||||
* designated by this handle. |
||||
* @param name |
||||
* the name of the field or method designated by this handle. |
||||
* @param desc |
||||
* the descriptor of the field or method designated by this |
||||
* handle. |
||||
* @param itf |
||||
* true if the owner is an interface. |
||||
*/ |
||||
public Handle(int tag, String owner, String name, String desc, boolean itf) { |
||||
this.tag = tag; |
||||
this.owner = owner; |
||||
this.name = name; |
||||
this.desc = desc; |
||||
this.itf = itf; |
||||
} |
||||
|
||||
/** |
||||
* Returns the kind of field or method designated by this handle. |
||||
* |
||||
* @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, |
||||
* {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, |
||||
* {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, |
||||
* {@link Opcodes#H_INVOKESPECIAL}, |
||||
* {@link Opcodes#H_NEWINVOKESPECIAL} or |
||||
* {@link Opcodes#H_INVOKEINTERFACE}. |
||||
*/ |
||||
public int getTag() { |
||||
return tag; |
||||
} |
||||
|
||||
/** |
||||
* Returns the internal name of the class that owns the field or method |
||||
* designated by this handle. |
||||
* |
||||
* @return the internal name of the class that owns the field or method |
||||
* designated by this handle. |
||||
*/ |
||||
public String getOwner() { |
||||
return owner; |
||||
} |
||||
|
||||
/** |
||||
* Returns the name of the field or method designated by this handle. |
||||
* |
||||
* @return the name of the field or method designated by this handle. |
||||
*/ |
||||
public String getName() { |
||||
return name; |
||||
} |
||||
|
||||
/** |
||||
* Returns the descriptor of the field or method designated by this handle. |
||||
* |
||||
* @return the descriptor of the field or method designated by this handle. |
||||
*/ |
||||
public String getDesc() { |
||||
return desc; |
||||
} |
||||
|
||||
/** |
||||
* Returns true if the owner of the field or method designated |
||||
* by this handle is an interface. |
||||
* |
||||
* @return true if the owner of the field or method designated |
||||
* by this handle is an interface. |
||||
*/ |
||||
public boolean isInterface() { |
||||
return itf; |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(Object obj) { |
||||
if (obj == this) { |
||||
return true; |
||||
} |
||||
if (!(obj instanceof Handle)) { |
||||
return false; |
||||
} |
||||
Handle h = (Handle) obj; |
||||
return tag == h.tag && itf == h.itf && owner.equals(h.owner) |
||||
&& name.equals(h.name) && desc.equals(h.desc); |
||||
} |
||||
|
||||
@Override |
||||
public int hashCode() { |
||||
return tag + (itf? 64: 0) + owner.hashCode() * name.hashCode() * desc.hashCode(); |
||||
} |
||||
|
||||
/** |
||||
* Returns the textual representation of this handle. The textual |
||||
* representation is: |
||||
* |
||||
* <pre> |
||||
* for a reference to a class: |
||||
* owner '.' name desc ' ' '(' tag ')' |
||||
* for a reference to an interface: |
||||
* owner '.' name desc ' ' '(' tag ' ' itf ')' |
||||
* </pre> |
||||
* |
||||
* . As this format is unambiguous, it can be parsed if necessary. |
||||
*/ |
||||
@Override |
||||
public String toString() { |
||||
return owner + '.' + name + desc + " (" + tag + (itf? " itf": "") + ')'; |
||||
} |
||||
} |
@ -1,121 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* Information about an exception handler block. |
||||
* |
||||
* @author Eric Bruneton |
||||
*/ |
||||
class Handler { |
||||
|
||||
/** |
||||
* Beginning of the exception handler's scope (inclusive). |
||||
*/ |
||||
Label start; |
||||
|
||||
/** |
||||
* End of the exception handler's scope (exclusive). |
||||
*/ |
||||
Label end; |
||||
|
||||
/** |
||||
* Beginning of the exception handler's code. |
||||
*/ |
||||
Label handler; |
||||
|
||||
/** |
||||
* Internal name of the type of exceptions handled by this handler, or |
||||
* <tt>null</tt> to catch any exceptions. |
||||
*/ |
||||
String desc; |
||||
|
||||
/** |
||||
* Constant pool index of the internal name of the type of exceptions |
||||
* handled by this handler, or 0 to catch any exceptions. |
||||
*/ |
||||
int type; |
||||
|
||||
/** |
||||
* Next exception handler block info. |
||||
*/ |
||||
Handler next; |
||||
|
||||
/** |
||||
* Removes the range between start and end from the given exception |
||||
* handlers. |
||||
* |
||||
* @param h |
||||
* an exception handler list. |
||||
* @param start |
||||
* the start of the range to be removed. |
||||
* @param end |
||||
* the end of the range to be removed. Maybe null. |
||||
* @return the exception handler list with the start-end range removed. |
||||
*/ |
||||
static Handler remove(Handler h, Label start, Label end) { |
||||
if (h == null) { |
||||
return null; |
||||
} else { |
||||
h.next = remove(h.next, start, end); |
||||
} |
||||
int hstart = h.start.position; |
||||
int hend = h.end.position; |
||||
int s = start.position; |
||||
int e = end == null ? Integer.MAX_VALUE : end.position; |
||||
// if [hstart,hend[ and [s,e[ intervals intersect...
|
||||
if (s < hend && e > hstart) { |
||||
if (s <= hstart) { |
||||
if (e >= hend) { |
||||
// [hstart,hend[ fully included in [s,e[, h removed
|
||||
h = h.next; |
||||
} else { |
||||
// [hstart,hend[ minus [s,e[ = [e,hend[
|
||||
h.start = end; |
||||
} |
||||
} else if (e >= hend) { |
||||
// [hstart,hend[ minus [s,e[ = [hstart,s[
|
||||
h.end = start; |
||||
} else { |
||||
// [hstart,hend[ minus [s,e[ = [hstart,s[ + [e,hend[
|
||||
Handler g = new Handler(); |
||||
g.start = end; |
||||
g.end = h.end; |
||||
g.handler = h.handler; |
||||
g.desc = h.desc; |
||||
g.type = h.type; |
||||
g.next = h.next; |
||||
h.end = start; |
||||
h.next = g; |
||||
} |
||||
} |
||||
return h; |
||||
} |
||||
} |
@ -1,318 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* A constant pool item. Constant pool items can be created with the 'newXXX' |
||||
* methods in the {@link ClassWriter} class. |
||||
* |
||||
* @author Eric Bruneton |
||||
*/ |
||||
final class Item { |
||||
|
||||
/** |
||||
* Index of this item in the constant pool. |
||||
*/ |
||||
int index; |
||||
|
||||
/** |
||||
* Type of this constant pool item. A single class is used to represent all |
||||
* constant pool item types, in order to minimize the bytecode size of this |
||||
* package. The value of this field is one of {@link ClassWriter#INT}, |
||||
* {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT}, |
||||
* {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8}, |
||||
* {@link ClassWriter#STR}, {@link ClassWriter#CLASS}, |
||||
* {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD}, |
||||
* {@link ClassWriter#METH}, {@link ClassWriter#IMETH}, |
||||
* {@link ClassWriter#MODULE}, {@link ClassWriter#PACKAGE}, |
||||
* {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}. |
||||
* |
||||
* MethodHandle constant 9 variations are stored using a range of 9 values |
||||
* from {@link ClassWriter#HANDLE_BASE} + 1 to |
||||
* {@link ClassWriter#HANDLE_BASE} + 9. |
||||
* |
||||
* Special Item types are used for Items that are stored in the ClassWriter |
||||
* {@link ClassWriter#typeTable}, instead of the constant pool, in order to |
||||
* avoid clashes with normal constant pool items in the ClassWriter constant |
||||
* pool's hash table. These special item types are |
||||
* {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and |
||||
* {@link ClassWriter#TYPE_MERGED}. |
||||
*/ |
||||
int type; |
||||
|
||||
/** |
||||
* Value of this item, for an integer item. |
||||
*/ |
||||
int intVal; |
||||
|
||||
/** |
||||
* Value of this item, for a long item. |
||||
*/ |
||||
long longVal; |
||||
|
||||
/** |
||||
* First part of the value of this item, for items that do not hold a |
||||
* primitive value. |
||||
*/ |
||||
String strVal1; |
||||
|
||||
/** |
||||
* Second part of the value of this item, for items that do not hold a |
||||
* primitive value. |
||||
*/ |
||||
String strVal2; |
||||
|
||||
/** |
||||
* Third part of the value of this item, for items that do not hold a |
||||
* primitive value. |
||||
*/ |
||||
String strVal3; |
||||
|
||||
/** |
||||
* The hash code value of this constant pool item. |
||||
*/ |
||||
int hashCode; |
||||
|
||||
/** |
||||
* Link to another constant pool item, used for collision lists in the |
||||
* constant pool's hash table. |
||||
*/ |
||||
Item next; |
||||
|
||||
/** |
||||
* Constructs an uninitialized {@link Item}. |
||||
*/ |
||||
Item() { |
||||
} |
||||
|
||||
/** |
||||
* Constructs an uninitialized {@link Item} for constant pool element at |
||||
* given position. |
||||
* |
||||
* @param index |
||||
* index of the item to be constructed. |
||||
*/ |
||||
Item(final int index) { |
||||
this.index = index; |
||||
} |
||||
|
||||
/** |
||||
* Constructs a copy of the given item. |
||||
* |
||||
* @param index |
||||
* index of the item to be constructed. |
||||
* @param i |
||||
* the item that must be copied into the item to be constructed. |
||||
*/ |
||||
Item(final int index, final Item i) { |
||||
this.index = index; |
||||
type = i.type; |
||||
intVal = i.intVal; |
||||
longVal = i.longVal; |
||||
strVal1 = i.strVal1; |
||||
strVal2 = i.strVal2; |
||||
strVal3 = i.strVal3; |
||||
hashCode = i.hashCode; |
||||
} |
||||
|
||||
/** |
||||
* Sets this item to an integer item. |
||||
* |
||||
* @param intVal |
||||
* the value of this item. |
||||
*/ |
||||
void set(final int intVal) { |
||||
this.type = ClassWriter.INT; |
||||
this.intVal = intVal; |
||||
this.hashCode = 0x7FFFFFFF & (type + intVal); |
||||
} |
||||
|
||||
/** |
||||
* Sets this item to a long item. |
||||
* |
||||
* @param longVal |
||||
* the value of this item. |
||||
*/ |
||||
void set(final long longVal) { |
||||
this.type = ClassWriter.LONG; |
||||
this.longVal = longVal; |
||||
this.hashCode = 0x7FFFFFFF & (type + (int) longVal); |
||||
} |
||||
|
||||
/** |
||||
* Sets this item to a float item. |
||||
* |
||||
* @param floatVal |
||||
* the value of this item. |
||||
*/ |
||||
void set(final float floatVal) { |
||||
this.type = ClassWriter.FLOAT; |
||||
this.intVal = Float.floatToRawIntBits(floatVal); |
||||
this.hashCode = 0x7FFFFFFF & (type + (int) floatVal); |
||||
} |
||||
|
||||
/** |
||||
* Sets this item to a double item. |
||||
* |
||||
* @param doubleVal |
||||
* the value of this item. |
||||
*/ |
||||
void set(final double doubleVal) { |
||||
this.type = ClassWriter.DOUBLE; |
||||
this.longVal = Double.doubleToRawLongBits(doubleVal); |
||||
this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal); |
||||
} |
||||
|
||||
/** |
||||
* Sets this item to an item that do not hold a primitive value. |
||||
* |
||||
* @param type |
||||
* the type of this item. |
||||
* @param strVal1 |
||||
* first part of the value of this item. |
||||
* @param strVal2 |
||||
* second part of the value of this item. |
||||
* @param strVal3 |
||||
* third part of the value of this item. |
||||
*/ |
||||
@SuppressWarnings("fallthrough") |
||||
void set(final int type, final String strVal1, final String strVal2, |
||||
final String strVal3) { |
||||
this.type = type; |
||||
this.strVal1 = strVal1; |
||||
this.strVal2 = strVal2; |
||||
this.strVal3 = strVal3; |
||||
switch (type) { |
||||
case ClassWriter.CLASS: |
||||
this.intVal = 0; // intVal of a class must be zero, see visitInnerClass
|
||||
case ClassWriter.UTF8: |
||||
case ClassWriter.STR: |
||||
case ClassWriter.MTYPE: |
||||
case ClassWriter.MODULE: |
||||
case ClassWriter.PACKAGE: |
||||
case ClassWriter.TYPE_NORMAL: |
||||
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()); |
||||
return; |
||||
case ClassWriter.NAME_TYPE: { |
||||
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() |
||||
* strVal2.hashCode()); |
||||
return; |
||||
} |
||||
// ClassWriter.FIELD:
|
||||
// ClassWriter.METH:
|
||||
// ClassWriter.IMETH:
|
||||
// ClassWriter.HANDLE_BASE + 1..9
|
||||
default: |
||||
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() |
||||
* strVal2.hashCode() * strVal3.hashCode()); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Sets the item to an InvokeDynamic item. |
||||
* |
||||
* @param name |
||||
* invokedynamic's name. |
||||
* @param desc |
||||
* invokedynamic's desc. |
||||
* @param bsmIndex |
||||
* zero based index into the class attribute BootrapMethods. |
||||
*/ |
||||
void set(String name, String desc, int bsmIndex) { |
||||
this.type = ClassWriter.INDY; |
||||
this.longVal = bsmIndex; |
||||
this.strVal1 = name; |
||||
this.strVal2 = desc; |
||||
this.hashCode = 0x7FFFFFFF & (ClassWriter.INDY + bsmIndex |
||||
* strVal1.hashCode() * strVal2.hashCode()); |
||||
} |
||||
|
||||
/** |
||||
* Sets the item to a BootstrapMethod item. |
||||
* |
||||
* @param position |
||||
* position in byte in the class attribute BootrapMethods. |
||||
* @param hashCode |
||||
* hashcode of the item. This hashcode is processed from the |
||||
* hashcode of the bootstrap method and the hashcode of all |
||||
* bootstrap arguments. |
||||
*/ |
||||
void set(int position, int hashCode) { |
||||
this.type = ClassWriter.BSM; |
||||
this.intVal = position; |
||||
this.hashCode = hashCode; |
||||
} |
||||
|
||||
/** |
||||
* Indicates if the given item is equal to this one. <i>This method assumes |
||||
* that the two items have the same {@link #type}</i>. |
||||
* |
||||
* @param i |
||||
* the item to be compared to this one. Both items must have the |
||||
* same {@link #type}. |
||||
* @return <tt>true</tt> if the given item if equal to this one, |
||||
* <tt>false</tt> otherwise. |
||||
*/ |
||||
boolean isEqualTo(final Item i) { |
||||
switch (type) { |
||||
case ClassWriter.UTF8: |
||||
case ClassWriter.STR: |
||||
case ClassWriter.CLASS: |
||||
case ClassWriter.MODULE: |
||||
case ClassWriter.PACKAGE: |
||||
case ClassWriter.MTYPE: |
||||
case ClassWriter.TYPE_NORMAL: |
||||
return i.strVal1.equals(strVal1); |
||||
case ClassWriter.TYPE_MERGED: |
||||
case ClassWriter.LONG: |
||||
case ClassWriter.DOUBLE: |
||||
return i.longVal == longVal; |
||||
case ClassWriter.INT: |
||||
case ClassWriter.FLOAT: |
||||
return i.intVal == intVal; |
||||
case ClassWriter.TYPE_UNINIT: |
||||
return i.intVal == intVal && i.strVal1.equals(strVal1); |
||||
case ClassWriter.NAME_TYPE: |
||||
return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2); |
||||
case ClassWriter.INDY: { |
||||
return i.longVal == longVal && i.strVal1.equals(strVal1) |
||||
&& i.strVal2.equals(strVal2); |
||||
} |
||||
// case ClassWriter.FIELD:
|
||||
// case ClassWriter.METH:
|
||||
// case ClassWriter.IMETH:
|
||||
// case ClassWriter.HANDLE_BASE + 1..9
|
||||
default: |
||||
return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2) |
||||
&& i.strVal3.equals(strVal3); |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,564 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* A label represents a position in the bytecode of a method. Labels are used |
||||
* for jump, goto, and switch instructions, and for try catch blocks. A label |
||||
* designates the <i>instruction</i> that is just after. Note however that there |
||||
* can be other elements between a label and the instruction it designates (such |
||||
* as other labels, stack map frames, line numbers, etc.). |
||||
* |
||||
* @author Eric Bruneton |
||||
*/ |
||||
public class Label { |
||||
|
||||
/** |
||||
* Indicates if this label is only used for debug attributes. Such a label |
||||
* is not the start of a basic block, the target of a jump instruction, or |
||||
* an exception handler. It can be safely ignored in control flow graph |
||||
* analysis algorithms (for optimization purposes). |
||||
*/ |
||||
static final int DEBUG = 1; |
||||
|
||||
/** |
||||
* Indicates if the position of this label is known. |
||||
*/ |
||||
static final int RESOLVED = 2; |
||||
|
||||
/** |
||||
* Indicates if this label has been updated, after instruction resizing. |
||||
*/ |
||||
static final int RESIZED = 4; |
||||
|
||||
/** |
||||
* Indicates if this basic block has been pushed in the basic block stack. |
||||
* See {@link MethodWriter#visitMaxs visitMaxs}. |
||||
*/ |
||||
static final int PUSHED = 8; |
||||
|
||||
/** |
||||
* Indicates if this label is the target of a jump instruction, or the start |
||||
* of an exception handler. |
||||
*/ |
||||
static final int TARGET = 16; |
||||
|
||||
/** |
||||
* Indicates if a stack map frame must be stored for this label. |
||||
*/ |
||||
static final int STORE = 32; |
||||
|
||||
/** |
||||
* Indicates if this label corresponds to a reachable basic block. |
||||
*/ |
||||
static final int REACHABLE = 64; |
||||
|
||||
/** |
||||
* Indicates if this basic block ends with a JSR instruction. |
||||
*/ |
||||
static final int JSR = 128; |
||||
|
||||
/** |
||||
* Indicates if this basic block ends with a RET instruction. |
||||
*/ |
||||
static final int RET = 256; |
||||
|
||||
/** |
||||
* Indicates if this basic block is the start of a subroutine. |
||||
*/ |
||||
static final int SUBROUTINE = 512; |
||||
|
||||
/** |
||||
* Indicates if this subroutine basic block has been visited by a |
||||
* visitSubroutine(null, ...) call. |
||||
*/ |
||||
static final int VISITED = 1024; |
||||
|
||||
/** |
||||
* Indicates if this subroutine basic block has been visited by a |
||||
* visitSubroutine(!null, ...) call. |
||||
*/ |
||||
static final int VISITED2 = 2048; |
||||
|
||||
/** |
||||
* Field used to associate user information to a label. Warning: this field |
||||
* is used by the ASM tree package. In order to use it with the ASM tree |
||||
* package you must override the |
||||
* {@link com.fr.third.org.objectweb.asm.tree.MethodNode#getLabelNode} method. |
||||
*/ |
||||
public Object info; |
||||
|
||||
/** |
||||
* Flags that indicate the status of this label. |
||||
* |
||||
* @see #DEBUG |
||||
* @see #RESOLVED |
||||
* @see #RESIZED |
||||
* @see #PUSHED |
||||
* @see #TARGET |
||||
* @see #STORE |
||||
* @see #REACHABLE |
||||
* @see #JSR |
||||
* @see #RET |
||||
*/ |
||||
int status; |
||||
|
||||
/** |
||||
* The line number corresponding to this label, if known. If there are |
||||
* several lines, each line is stored in a separate label, all linked via |
||||
* their next field (these links are created in ClassReader and removed just |
||||
* before visitLabel is called, so that this does not impact the rest of the |
||||
* code). |
||||
*/ |
||||
int line; |
||||
|
||||
/** |
||||
* The position of this label in the code, if known. |
||||
*/ |
||||
int position; |
||||
|
||||
/** |
||||
* Number of forward references to this label, times two. |
||||
*/ |
||||
private int referenceCount; |
||||
|
||||
/** |
||||
* Informations about forward references. Each forward reference is |
||||
* described by two consecutive integers in this array: the first one is the |
||||
* position of the first byte of the bytecode instruction that contains the |
||||
* forward reference, while the second is the position of the first byte of |
||||
* the forward reference itself. In fact the sign of the first integer |
||||
* indicates if this reference uses 2 or 4 bytes, and its absolute value |
||||
* gives the position of the bytecode instruction. This array is also used |
||||
* as a bitset to store the subroutines to which a basic block belongs. This |
||||
* information is needed in {@linked MethodWriter#visitMaxs}, after all |
||||
* forward references have been resolved. Hence the same array can be used |
||||
* for both purposes without problems. |
||||
*/ |
||||
private int[] srcAndRefPositions; |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/* |
||||
* Fields for the control flow and data flow graph analysis algorithms (used |
||||
* to compute the maximum stack size or the stack map frames). A control |
||||
* flow graph contains one node per "basic block", and one edge per "jump" |
||||
* from one basic block to another. Each node (i.e., each basic block) is |
||||
* represented by the Label object that corresponds to the first instruction |
||||
* of this basic block. Each node also stores the list of its successors in |
||||
* the graph, as a linked list of Edge objects. |
||||
* |
||||
* The control flow analysis algorithms used to compute the maximum stack |
||||
* size or the stack map frames are similar and use two steps. The first |
||||
* step, during the visit of each instruction, builds information about the |
||||
* state of the local variables and the operand stack at the end of each |
||||
* basic block, called the "output frame", <i>relatively</i> to the frame |
||||
* state at the beginning of the basic block, which is called the "input |
||||
* frame", and which is <i>unknown</i> during this step. The second step, in |
||||
* {@link MethodWriter#visitMaxs}, is a fix point algorithm that computes |
||||
* information about the input frame of each basic block, from the input |
||||
* state of the first basic block (known from the method signature), and by |
||||
* the using the previously computed relative output frames. |
||||
* |
||||
* The algorithm used to compute the maximum stack size only computes the |
||||
* relative output and absolute input stack heights, while the algorithm |
||||
* used to compute stack map frames computes relative output frames and |
||||
* absolute input frames. |
||||
*/ |
||||
|
||||
/** |
||||
* Start of the output stack relatively to the input stack. The exact |
||||
* semantics of this field depends on the algorithm that is used. |
||||
* |
||||
* When only the maximum stack size is computed, this field is the number of |
||||
* elements in the input stack. |
||||
* |
||||
* When the stack map frames are completely computed, this field is the |
||||
* offset of the first output stack element relatively to the top of the |
||||
* input stack. This offset is always negative or null. A null offset means |
||||
* that the output stack must be appended to the input stack. A -n offset |
||||
* means that the first n output stack elements must replace the top n input |
||||
* stack elements, and that the other elements must be appended to the input |
||||
* stack. |
||||
*/ |
||||
int inputStackTop; |
||||
|
||||
/** |
||||
* Maximum height reached by the output stack, relatively to the top of the |
||||
* input stack. This maximum is always positive or null. |
||||
*/ |
||||
int outputStackMax; |
||||
|
||||
/** |
||||
* Information about the input and output stack map frames of this basic |
||||
* block. This field is only used when {@link ClassWriter#COMPUTE_FRAMES} |
||||
* option is used. |
||||
*/ |
||||
Frame frame; |
||||
|
||||
/** |
||||
* The successor of this label, in the order they are visited. This linked |
||||
* list does not include labels used for debug info only. If |
||||
* {@link ClassWriter#COMPUTE_FRAMES} option is used then, in addition, it |
||||
* does not contain successive labels that denote the same bytecode position |
||||
* (in this case only the first label appears in this list). |
||||
*/ |
||||
Label successor; |
||||
|
||||
/** |
||||
* The successors of this node in the control flow graph. These successors |
||||
* are stored in a linked list of {@link Edge Edge} objects, linked to each |
||||
* other by their {@link Edge#next} field. |
||||
*/ |
||||
Edge successors; |
||||
|
||||
/** |
||||
* The next basic block in the basic block stack. This stack is used in the |
||||
* main loop of the fix point algorithm used in the second step of the |
||||
* control flow analysis algorithms. It is also used in |
||||
* {@link #visitSubroutine} to avoid using a recursive method, and in |
||||
* ClassReader to temporarily store multiple source lines for a label. |
||||
* |
||||
* @see MethodWriter#visitMaxs |
||||
*/ |
||||
Label next; |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Constructs a new label. |
||||
*/ |
||||
public Label() { |
||||
} |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Methods to compute offsets and to manage forward references
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* 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 |
||||
* {@link Attribute} sub classes, and is normally not needed by class
|
||||
* generators or adapters.</i> |
||||
* |
||||
* @return the offset corresponding to this label. |
||||
* @throws IllegalStateException |
||||
* if this label is not resolved yet. |
||||
*/ |
||||
public int getOffset() { |
||||
if ((status & RESOLVED) == 0) { |
||||
throw new IllegalStateException( |
||||
"Label offset position has not been resolved yet"); |
||||
} |
||||
return position; |
||||
} |
||||
|
||||
/** |
||||
* Puts a reference to this label in the bytecode of a method. If the |
||||
* position of the label is known, the offset is computed and written |
||||
* directly. Otherwise, a null offset is written and a new forward reference |
||||
* is declared for this label. |
||||
* |
||||
* @param owner |
||||
* the code writer that calls this method. |
||||
* @param out |
||||
* the bytecode of the method. |
||||
* @param source |
||||
* the position of first byte of the bytecode instruction that |
||||
* contains this label. |
||||
* @param wideOffset |
||||
* <tt>true</tt> if the reference must be stored in 4 bytes, or |
||||
* <tt>false</tt> if it must be stored with 2 bytes. |
||||
* @throws IllegalArgumentException |
||||
* if this label has not been created by the given code writer. |
||||
*/ |
||||
void put(final MethodWriter owner, final ByteVector out, final int source, |
||||
final boolean wideOffset) { |
||||
if ((status & RESOLVED) == 0) { |
||||
if (wideOffset) { |
||||
addReference(-1 - source, out.length); |
||||
out.putInt(-1); |
||||
} else { |
||||
addReference(source, out.length); |
||||
out.putShort(-1); |
||||
} |
||||
} else { |
||||
if (wideOffset) { |
||||
out.putInt(position - source); |
||||
} else { |
||||
out.putShort(position - source); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Adds a forward reference to this label. This method must be called only |
||||
* for a true forward reference, i.e. only if this label is not resolved |
||||
* yet. For backward references, the offset of the reference can be, and |
||||
* must be, computed and stored directly. |
||||
* |
||||
* @param sourcePosition |
||||
* the position of the referencing instruction. This position |
||||
* will be used to compute the offset of this forward reference. |
||||
* @param referencePosition |
||||
* the position where the offset for this forward reference must |
||||
* be stored. |
||||
*/ |
||||
private void addReference(final int sourcePosition, |
||||
final int referencePosition) { |
||||
if (srcAndRefPositions == null) { |
||||
srcAndRefPositions = new int[6]; |
||||
} |
||||
if (referenceCount >= srcAndRefPositions.length) { |
||||
int[] a = new int[srcAndRefPositions.length + 6]; |
||||
System.arraycopy(srcAndRefPositions, 0, a, 0, |
||||
srcAndRefPositions.length); |
||||
srcAndRefPositions = a; |
||||
} |
||||
srcAndRefPositions[referenceCount++] = sourcePosition; |
||||
srcAndRefPositions[referenceCount++] = referencePosition; |
||||
} |
||||
|
||||
/** |
||||
* Resolves all forward references to this label. This method must be called |
||||
* when this label is added to the bytecode of the method, i.e. when its |
||||
* position becomes known. This method fills in the blanks that where left |
||||
* in the bytecode by each forward reference previously added to this label. |
||||
* |
||||
* @param owner |
||||
* the code writer that calls this method. |
||||
* @param position |
||||
* the position of this label in the bytecode. |
||||
* @param data |
||||
* the bytecode of the method. |
||||
* @return <tt>true</tt> if a blank that was left for this label was too |
||||
* small to store the offset. In such a case the corresponding jump |
||||
* instruction is replaced with a pseudo instruction (using unused |
||||
* opcodes) using an unsigned two bytes offset. These pseudo |
||||
* instructions will be replaced with standard bytecode instructions |
||||
* with wider offsets (4 bytes instead of 2), in ClassReader. |
||||
* @throws IllegalArgumentException |
||||
* if this label has already been resolved, or if it has not |
||||
* been created by the given code writer. |
||||
*/ |
||||
boolean resolve(final MethodWriter owner, final int position, |
||||
final byte[] data) { |
||||
boolean needUpdate = false; |
||||
this.status |= RESOLVED; |
||||
this.position = position; |
||||
int i = 0; |
||||
while (i < referenceCount) { |
||||
int source = srcAndRefPositions[i++]; |
||||
int reference = srcAndRefPositions[i++]; |
||||
int offset; |
||||
if (source >= 0) { |
||||
offset = position - source; |
||||
if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) { |
||||
/* |
||||
* changes the opcode of the jump instruction, in order to |
||||
* be able to find it later (see resizeInstructions in |
||||
* MethodWriter). These temporary opcodes are similar to |
||||
* jump instruction opcodes, except that the 2 bytes offset |
||||
* is unsigned (and can therefore represent values from 0 to |
||||
* 65535, which is sufficient since the size of a method is |
||||
* limited to 65535 bytes). |
||||
*/ |
||||
int opcode = data[reference - 1] & 0xFF; |
||||
if (opcode <= Opcodes.JSR) { |
||||
// changes IFEQ ... JSR to opcodes 202 to 217
|
||||
data[reference - 1] = (byte) (opcode + 49); |
||||
} else { |
||||
// changes IFNULL and IFNONNULL to opcodes 218 and 219
|
||||
data[reference - 1] = (byte) (opcode + 20); |
||||
} |
||||
needUpdate = true; |
||||
} |
||||
data[reference++] = (byte) (offset >>> 8); |
||||
data[reference] = (byte) offset; |
||||
} else { |
||||
offset = position + source + 1; |
||||
data[reference++] = (byte) (offset >>> 24); |
||||
data[reference++] = (byte) (offset >>> 16); |
||||
data[reference++] = (byte) (offset >>> 8); |
||||
data[reference] = (byte) offset; |
||||
} |
||||
} |
||||
return needUpdate; |
||||
} |
||||
|
||||
/** |
||||
* Returns the first label of the series to which this label belongs. For an |
||||
* isolated label or for the first label in a series of successive labels, |
||||
* this method returns the label itself. For other labels it returns the |
||||
* first label of the series. |
||||
* |
||||
* @return the first label of the series to which this label belongs. |
||||
*/ |
||||
Label getFirst() { |
||||
return frame == null ? this : frame.owner; |
||||
} |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Methods related to subroutines
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Returns true is this basic block belongs to the given subroutine. |
||||
* |
||||
* @param id |
||||
* a subroutine id. |
||||
* @return true is this basic block belongs to the given subroutine. |
||||
*/ |
||||
boolean inSubroutine(final long id) { |
||||
if ((status & Label.VISITED) != 0) { |
||||
return (srcAndRefPositions[(int) (id >>> 32)] & (int) id) != 0; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Returns true if this basic block and the given one belong to a common |
||||
* subroutine. |
||||
* |
||||
* @param block |
||||
* another basic block. |
||||
* @return true if this basic block and the given one belong to a common |
||||
* subroutine. |
||||
*/ |
||||
boolean inSameSubroutine(final Label block) { |
||||
if ((status & VISITED) == 0 || (block.status & VISITED) == 0) { |
||||
return false; |
||||
} |
||||
for (int i = 0; i < srcAndRefPositions.length; ++i) { |
||||
if ((srcAndRefPositions[i] & block.srcAndRefPositions[i]) != 0) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Marks this basic block as belonging to the given subroutine. |
||||
* |
||||
* @param id |
||||
* a subroutine id. |
||||
* @param nbSubroutines |
||||
* the total number of subroutines in the method. |
||||
*/ |
||||
void addToSubroutine(final long id, final int nbSubroutines) { |
||||
if ((status & VISITED) == 0) { |
||||
status |= VISITED; |
||||
srcAndRefPositions = new int[nbSubroutines / 32 + 1]; |
||||
} |
||||
srcAndRefPositions[(int) (id >>> 32)] |= (int) id; |
||||
} |
||||
|
||||
/** |
||||
* Finds the basic blocks that belong to a given subroutine, and marks these |
||||
* blocks as belonging to this subroutine. This method follows the control |
||||
* flow graph to find all the blocks that are reachable from the current |
||||
* block WITHOUT following any JSR target. |
||||
* |
||||
* @param JSR |
||||
* a JSR block that jumps to this subroutine. If this JSR is not |
||||
* null it is added to the successor of the RET blocks found in |
||||
* the subroutine. |
||||
* @param id |
||||
* the id of this subroutine. |
||||
* @param nbSubroutines |
||||
* the total number of subroutines in the method. |
||||
*/ |
||||
void visitSubroutine(final Label JSR, final long id, final int nbSubroutines) { |
||||
// user managed stack of labels, to avoid using a recursive method
|
||||
// (recursivity can lead to stack overflow with very large methods)
|
||||
Label stack = this; |
||||
while (stack != null) { |
||||
// removes a label l from the stack
|
||||
Label l = stack; |
||||
stack = l.next; |
||||
l.next = null; |
||||
|
||||
if (JSR != null) { |
||||
if ((l.status & VISITED2) != 0) { |
||||
continue; |
||||
} |
||||
l.status |= VISITED2; |
||||
// adds JSR to the successors of l, if it is a RET block
|
||||
if ((l.status & RET) != 0) { |
||||
if (!l.inSameSubroutine(JSR)) { |
||||
Edge e = new Edge(); |
||||
e.info = l.inputStackTop; |
||||
e.successor = JSR.successors.successor; |
||||
e.next = l.successors; |
||||
l.successors = e; |
||||
} |
||||
} |
||||
} else { |
||||
// if the l block already belongs to subroutine 'id', continue
|
||||
if (l.inSubroutine(id)) { |
||||
continue; |
||||
} |
||||
// marks the l block as belonging to subroutine 'id'
|
||||
l.addToSubroutine(id, nbSubroutines); |
||||
} |
||||
// pushes each successor of l on the stack, except JSR targets
|
||||
Edge e = l.successors; |
||||
while (e != null) { |
||||
// if the l block is a JSR block, then 'l.successors.next' leads
|
||||
// to the JSR target (see {@link #visitJumpInsn}) and must
|
||||
// therefore not be followed
|
||||
if ((l.status & Label.JSR) == 0 || e != l.successors.next) { |
||||
// pushes e.successor on the stack if it not already added
|
||||
if (e.successor.next == null) { |
||||
e.successor.next = stack; |
||||
stack = e.successor; |
||||
} |
||||
} |
||||
e = e.next; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Overriden Object methods
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Returns a string representation of this label. |
||||
* |
||||
* @return a string representation of this label. |
||||
*/ |
||||
@Override |
||||
public String toString() { |
||||
return "L" + System.identityHashCode(this); |
||||
} |
||||
} |
@ -1,881 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* A visitor to visit a Java method. The methods of this class must be called in |
||||
* the following order: ( <tt>visitParameter</tt> )* [ |
||||
* <tt>visitAnnotationDefault</tt> ] ( <tt>visitAnnotation</tt> | |
||||
* <tt>visitParameterAnnotation</tt> <tt>visitTypeAnnotation</tt> | |
||||
* <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> | |
||||
* <tt>visit<i>X</i>Insn</tt> | <tt>visitLabel</tt> | |
||||
* <tt>visitInsnAnnotation</tt> | <tt>visitTryCatchBlock</tt> | |
||||
* <tt>visitTryCatchAnnotation</tt> | <tt>visitLocalVariable</tt> | |
||||
* <tt>visitLocalVariableAnnotation</tt> | <tt>visitLineNumber</tt> )* |
||||
* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In addition, the |
||||
* <tt>visit<i>X</i>Insn</tt> and <tt>visitLabel</tt> methods must be called in |
||||
* the sequential order of the bytecode instructions of the visited code, |
||||
* <tt>visitInsnAnnotation</tt> must be called <i>after</i> the annotated |
||||
* instruction, <tt>visitTryCatchBlock</tt> must be called <i>before</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 |
||||
*/ |
||||
public abstract class MethodVisitor { |
||||
|
||||
/** |
||||
* The ASM API version implemented by this visitor. The value of this field |
||||
* must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. |
||||
*/ |
||||
protected final int api; |
||||
|
||||
/** |
||||
* The method visitor to which this visitor must delegate method calls. May |
||||
* be null. |
||||
*/ |
||||
protected MethodVisitor mv; |
||||
|
||||
/** |
||||
* Constructs a new {@link MethodVisitor}. |
||||
* |
||||
* @param api |
||||
* the ASM API version implemented by this visitor. Must be one |
||||
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. |
||||
*/ |
||||
public MethodVisitor(final int api) { |
||||
this(api, null); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a new {@link MethodVisitor}. |
||||
* |
||||
* @param api |
||||
* the ASM API version implemented by this visitor. Must be one |
||||
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. |
||||
* @param mv |
||||
* the method visitor to which this visitor must delegate method |
||||
* calls. May be null. |
||||
*/ |
||||
public MethodVisitor(final int api, final MethodVisitor mv) { |
||||
if (api < Opcodes.ASM4 || api > Opcodes.ASM6) { |
||||
throw new IllegalArgumentException(); |
||||
} |
||||
this.api = api; |
||||
this.mv = mv; |
||||
} |
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// 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. |
||||
* |
||||
* @return a visitor to the visit the actual default value of this |
||||
* annotation interface method, or <tt>null</tt> if this visitor is |
||||
* not interested in visiting this default value. The 'name' |
||||
* parameters passed to the methods of this annotation visitor are |
||||
* ignored. Moreover, exacly one visit method must be called on this |
||||
* annotation visitor, followed by visitEnd. |
||||
*/ |
||||
public AnnotationVisitor visitAnnotationDefault() { |
||||
if (mv != null) { |
||||
return mv.visitAnnotationDefault(); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Visits an annotation of this method. |
||||
* |
||||
* @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 visitAnnotation(String desc, boolean visible) { |
||||
if (mv != null) { |
||||
return mv.visitAnnotation(desc, visible); |
||||
} |
||||
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. |
||||
* |
||||
* @param parameter |
||||
* the parameter index. |
||||
* @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 visitParameterAnnotation(int parameter, |
||||
String desc, boolean visible) { |
||||
if (mv != null) { |
||||
return mv.visitParameterAnnotation(parameter, desc, visible); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Visits a non standard attribute of this method. |
||||
* |
||||
* @param attr |
||||
* an attribute. |
||||
*/ |
||||
public void visitAttribute(Attribute attr) { |
||||
if (mv != null) { |
||||
mv.visitAttribute(attr); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Starts the visit of the method's code, if any (i.e. non abstract method). |
||||
*/ |
||||
public void visitCode() { |
||||
if (mv != null) { |
||||
mv.visitCode(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits the current state of the local variables and operand stack |
||||
* elements. This method must(*) be called <i>just before</i> any |
||||
* instruction <b>i</b> that follows an unconditional branch instruction |
||||
* such as GOTO or THROW, that is the target of a jump instruction, or that |
||||
* starts an exception handler block. The visited types must describe the |
||||
* values of the local variables and of the operand stack elements <i>just |
||||
* before</i> <b>i</b> is executed.<br> |
||||
* <br> |
||||
* (*) this is mandatory only for classes whose version is greater than or |
||||
* equal to {@link Opcodes#V1_6 V1_6}. <br> |
||||
* <br> |
||||
* The frames of a method must be given either in expanded form, or in |
||||
* compressed form (all frames must use the same format, i.e. you must not |
||||
* mix expanded and compressed frames within a single method): |
||||
* <ul> |
||||
* <li>In expanded form, all frames must have the F_NEW type.</li> |
||||
* <li>In compressed form, frames are basically "deltas" from the state of |
||||
* the previous frame: |
||||
* <ul> |
||||
* <li>{@link Opcodes#F_SAME} representing frame with exactly the same |
||||
* locals as the previous frame and with the empty stack.</li> |
||||
* <li>{@link Opcodes#F_SAME1} representing frame with exactly the same |
||||
* locals as the previous frame and with single value on the stack ( |
||||
* <code>nStack</code> is 1 and <code>stack[0]</code> contains value for the |
||||
* type of the stack item).</li> |
||||
* <li>{@link Opcodes#F_APPEND} representing frame with current locals are |
||||
* the same as the locals in the previous frame, except that additional |
||||
* locals are defined (<code>nLocal</code> is 1, 2 or 3 and |
||||
* <code>local</code> elements contains values representing added types).</li> |
||||
* <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 |
||||
* 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> |
||||
* </ul> |
||||
* </li> |
||||
* </ul> |
||||
* <br> |
||||
* In both cases the first frame, corresponding to the method's parameters |
||||
* and access flags, is implicit and must not be visited. Also, it is |
||||
* illegal to visit two or more frames for the same code location (i.e., at |
||||
* least one instruction must be visited between two calls to visitFrame). |
||||
* |
||||
* @param type |
||||
* the type of this stack map frame. Must be |
||||
* {@link Opcodes#F_NEW} for expanded frames, or |
||||
* {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, |
||||
* {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or |
||||
* {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for |
||||
* compressed frames. |
||||
* @param nLocal |
||||
* the number of local variables in the visited frame. |
||||
* @param local |
||||
* the local variable types in this frame. This array must not be |
||||
* modified. Primitive types are represented by |
||||
* {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, |
||||
* {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, |
||||
* {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or |
||||
* {@link Opcodes#UNINITIALIZED_THIS} (long and double are |
||||
* represented by a single element). Reference types are |
||||
* represented by String objects (representing internal names), |
||||
* and uninitialized types by Label objects (this label |
||||
* designates the NEW instruction that created this uninitialized |
||||
* value). |
||||
* @param nStack |
||||
* the number of operand stack elements in the visited frame. |
||||
* @param stack |
||||
* the operand stack types in this frame. This array must not be |
||||
* modified. Its content has the same format as the "local" |
||||
* array. |
||||
* @throws IllegalStateException |
||||
* if a frame is visited just after another one, without any |
||||
* instruction between the two (unless this frame is a |
||||
* Opcodes#F_SAME frame, in which case it is silently ignored). |
||||
*/ |
||||
public void visitFrame(int type, int nLocal, Object[] local, int nStack, |
||||
Object[] stack) { |
||||
if (mv != null) { |
||||
mv.visitFrame(type, nLocal, local, nStack, stack); |
||||
} |
||||
} |
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Normal instructions
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Visits a zero operand instruction. |
||||
* |
||||
* @param opcode |
||||
* the opcode of the instruction to be visited. This opcode is |
||||
* either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, |
||||
* ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, |
||||
* FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, |
||||
* LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, |
||||
* IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, |
||||
* SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, |
||||
* DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, |
||||
* IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, |
||||
* FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, |
||||
* IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, |
||||
* L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, |
||||
* LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN, |
||||
* DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, |
||||
* or MONITOREXIT. |
||||
*/ |
||||
public void visitInsn(int opcode) { |
||||
if (mv != null) { |
||||
mv.visitInsn(opcode); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits an instruction with a single int operand. |
||||
* |
||||
* @param opcode |
||||
* the opcode of the instruction to be visited. This opcode is |
||||
* either BIPUSH, SIPUSH or NEWARRAY. |
||||
* @param operand |
||||
* the operand of the instruction to be visited.<br> |
||||
* When opcode is BIPUSH, operand value should be between |
||||
* Byte.MIN_VALUE and Byte.MAX_VALUE.<br> |
||||
* When opcode is SIPUSH, operand value should be between |
||||
* Short.MIN_VALUE and Short.MAX_VALUE.<br> |
||||
* When opcode is NEWARRAY, operand value should be one of |
||||
* {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR}, |
||||
* {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, |
||||
* {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT}, |
||||
* {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}. |
||||
*/ |
||||
public void visitIntInsn(int opcode, int operand) { |
||||
if (mv != null) { |
||||
mv.visitIntInsn(opcode, operand); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits a local variable instruction. A local variable instruction is an |
||||
* instruction that loads or stores the value of a local variable. |
||||
* |
||||
* @param opcode |
||||
* the opcode of the local variable instruction to be visited. |
||||
* This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, |
||||
* ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET. |
||||
* @param var |
||||
* the operand of the instruction to be visited. This operand is |
||||
* the index of a local variable. |
||||
*/ |
||||
public void visitVarInsn(int opcode, int var) { |
||||
if (mv != null) { |
||||
mv.visitVarInsn(opcode, var); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits a type instruction. A type instruction is an instruction that |
||||
* takes the internal name of a class as parameter. |
||||
* |
||||
* @param opcode |
||||
* the opcode of the type instruction to be visited. This opcode |
||||
* is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF. |
||||
* @param type |
||||
* the operand of the instruction to be visited. This operand |
||||
* must be the internal name of an object or array class (see |
||||
* {@link Type#getInternalName() getInternalName}). |
||||
*/ |
||||
public void visitTypeInsn(int opcode, String type) { |
||||
if (mv != null) { |
||||
mv.visitTypeInsn(opcode, type); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits a field instruction. A field instruction is an instruction that |
||||
* loads or stores the value of a field of an object. |
||||
* |
||||
* @param opcode |
||||
* the opcode of the type instruction to be visited. This opcode |
||||
* is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. |
||||
* @param owner |
||||
* the internal name of the field's owner class (see |
||||
* {@link Type#getInternalName() getInternalName}). |
||||
* @param name |
||||
* the field's name. |
||||
* @param desc |
||||
* the field's descriptor (see {@link Type Type}). |
||||
*/ |
||||
public void visitFieldInsn(int opcode, String owner, String name, |
||||
String desc) { |
||||
if (mv != null) { |
||||
mv.visitFieldInsn(opcode, owner, name, desc); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits a method instruction. A method instruction is an instruction that |
||||
* invokes a method. |
||||
* |
||||
* @param opcode |
||||
* the opcode of the type instruction to be visited. This opcode |
||||
* is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or |
||||
* INVOKEINTERFACE. |
||||
* @param owner |
||||
* the internal name of the method's owner class (see |
||||
* {@link Type#getInternalName() getInternalName}). |
||||
* @param name |
||||
* the method's name. |
||||
* @param desc |
||||
* the method's descriptor (see {@link Type Type}). |
||||
*/ |
||||
@Deprecated |
||||
public void visitMethodInsn(int opcode, String owner, String name, |
||||
String desc) { |
||||
if (api >= Opcodes.ASM5) { |
||||
boolean itf = opcode == Opcodes.INVOKEINTERFACE; |
||||
visitMethodInsn(opcode, owner, name, desc, itf); |
||||
return; |
||||
} |
||||
if (mv != null) { |
||||
mv.visitMethodInsn(opcode, owner, name, desc); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits a method instruction. A method instruction is an instruction that |
||||
* invokes a method. |
||||
* |
||||
* @param opcode |
||||
* the opcode of the type instruction to be visited. This opcode |
||||
* is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or |
||||
* INVOKEINTERFACE. |
||||
* @param owner |
||||
* the internal name of the method's owner class (see |
||||
* {@link Type#getInternalName() getInternalName}). |
||||
* @param name |
||||
* the method's name. |
||||
* @param desc |
||||
* the method's descriptor (see {@link Type Type}). |
||||
* @param itf |
||||
* if the method's owner class is an interface. |
||||
*/ |
||||
public void visitMethodInsn(int opcode, String owner, String name, |
||||
String desc, boolean itf) { |
||||
if (api < Opcodes.ASM5) { |
||||
if (itf != (opcode == Opcodes.INVOKEINTERFACE)) { |
||||
throw new IllegalArgumentException( |
||||
"INVOKESPECIAL/STATIC on interfaces require ASM 5"); |
||||
} |
||||
visitMethodInsn(opcode, owner, name, desc); |
||||
return; |
||||
} |
||||
if (mv != null) { |
||||
mv.visitMethodInsn(opcode, owner, name, desc, itf); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits an invokedynamic instruction. |
||||
* |
||||
* @param name |
||||
* the method's name. |
||||
* @param desc |
||||
* the method's descriptor (see {@link Type Type}). |
||||
* @param bsm |
||||
* the bootstrap method. |
||||
* @param bsmArgs |
||||
* the bootstrap method constant arguments. Each argument must be |
||||
* an {@link Integer}, {@link Float}, {@link Long}, |
||||
* {@link Double}, {@link String}, {@link Type} or {@link Handle} |
||||
* value. This method is allowed to modify the content of the |
||||
* array so a caller should expect that this array may change. |
||||
*/ |
||||
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, |
||||
Object... bsmArgs) { |
||||
if (mv != null) { |
||||
mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits a jump instruction. A jump instruction is an instruction that may |
||||
* jump to another instruction. |
||||
* |
||||
* @param opcode |
||||
* the opcode of the type instruction to be visited. This opcode |
||||
* is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, |
||||
* IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, |
||||
* IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. |
||||
* @param label |
||||
* the operand of the instruction to be visited. This operand is |
||||
* a label that designates the instruction to which the jump |
||||
* instruction may jump. |
||||
*/ |
||||
public void visitJumpInsn(int opcode, Label label) { |
||||
if (mv != null) { |
||||
mv.visitJumpInsn(opcode, label); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits a label. A label designates the instruction that will be visited |
||||
* just after it. |
||||
* |
||||
* @param label |
||||
* a {@link Label Label} object. |
||||
*/ |
||||
public void visitLabel(Label label) { |
||||
if (mv != null) { |
||||
mv.visitLabel(label); |
||||
} |
||||
} |
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Special instructions
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Visits a LDC instruction. Note that new constant types may be added in |
||||
* future versions of the Java Virtual Machine. To easily detect new |
||||
* constant types, implementations of this method should check for |
||||
* unexpected constant types, like this: |
||||
* |
||||
* <pre> |
||||
* if (cst instanceof Integer) { |
||||
* // ...
|
||||
* } else if (cst instanceof Float) { |
||||
* // ...
|
||||
* } else if (cst instanceof Long) { |
||||
* // ...
|
||||
* } else if (cst instanceof Double) { |
||||
* // ...
|
||||
* } else if (cst instanceof String) { |
||||
* // ...
|
||||
* } else if (cst instanceof Type) { |
||||
* int sort = ((Type) cst).getSort(); |
||||
* if (sort == Type.OBJECT) { |
||||
* // ...
|
||||
* } else if (sort == Type.ARRAY) { |
||||
* // ...
|
||||
* } else if (sort == Type.METHOD) { |
||||
* // ...
|
||||
* } else { |
||||
* // throw an exception
|
||||
* } |
||||
* } else if (cst instanceof Handle) { |
||||
* // ...
|
||||
* } else { |
||||
* // throw an exception
|
||||
* } |
||||
* </pre> |
||||
* |
||||
* @param cst |
||||
* the constant to be loaded on the stack. This parameter must be |
||||
* a non null {@link Integer}, a {@link Float}, a {@link Long}, a |
||||
* {@link Double}, a {@link String}, a {@link Type} of OBJECT or |
||||
* ARRAY sort for <tt>.class</tt> constants, for classes whose |
||||
* version is 49.0, a {@link Type} of METHOD sort or a |
||||
* {@link Handle} for MethodType and MethodHandle constants, for |
||||
* classes whose version is 51.0. |
||||
*/ |
||||
public void visitLdcInsn(Object cst) { |
||||
if (mv != null) { |
||||
mv.visitLdcInsn(cst); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits an IINC instruction. |
||||
* |
||||
* @param var |
||||
* index of the local variable to be incremented. |
||||
* @param increment |
||||
* amount to increment the local variable by. |
||||
*/ |
||||
public void visitIincInsn(int var, int increment) { |
||||
if (mv != null) { |
||||
mv.visitIincInsn(var, increment); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits a TABLESWITCH instruction. |
||||
* |
||||
* @param min |
||||
* the minimum key value. |
||||
* @param max |
||||
* the maximum key value. |
||||
* @param dflt |
||||
* beginning of the default handler block. |
||||
* @param labels |
||||
* beginnings of the handler blocks. <tt>labels[i]</tt> is the |
||||
* beginning of the handler block for the <tt>min + i</tt> key. |
||||
*/ |
||||
public void visitTableSwitchInsn(int min, int max, Label dflt, |
||||
Label... labels) { |
||||
if (mv != null) { |
||||
mv.visitTableSwitchInsn(min, max, dflt, labels); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits a LOOKUPSWITCH instruction. |
||||
* |
||||
* @param dflt |
||||
* beginning of the default handler block. |
||||
* @param keys |
||||
* the values of the keys. |
||||
* @param labels |
||||
* beginnings of the handler blocks. <tt>labels[i]</tt> is the |
||||
* beginning of the handler block for the <tt>keys[i]</tt> key. |
||||
*/ |
||||
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { |
||||
if (mv != null) { |
||||
mv.visitLookupSwitchInsn(dflt, keys, labels); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits a MULTIANEWARRAY instruction. |
||||
* |
||||
* @param desc |
||||
* an array type descriptor (see {@link Type Type}). |
||||
* @param dims |
||||
* number of dimensions of the array to allocate. |
||||
*/ |
||||
public void visitMultiANewArrayInsn(String desc, int dims) { |
||||
if (mv != null) { |
||||
mv.visitMultiANewArrayInsn(desc, dims); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 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
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Visits a try catch block. |
||||
* |
||||
* @param start |
||||
* beginning of the exception handler's scope (inclusive). |
||||
* @param end |
||||
* end of the exception handler's scope (exclusive). |
||||
* @param handler |
||||
* beginning of the exception handler's code. |
||||
* @param type |
||||
* internal name of the type of exceptions handled by the |
||||
* handler, or <tt>null</tt> to catch any exceptions (for |
||||
* "finally" blocks). |
||||
* @throws IllegalArgumentException |
||||
* if one of the labels has already been visited by this visitor |
||||
* (by the {@link #visitLabel visitLabel} method). |
||||
*/ |
||||
public void visitTryCatchBlock(Label start, Label end, Label handler, |
||||
String type) { |
||||
if (mv != null) { |
||||
mv.visitTryCatchBlock(start, end, handler, type); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 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. |
||||
* |
||||
* @param name |
||||
* the name of a local variable. |
||||
* @param desc |
||||
* the type descriptor of this local variable. |
||||
* @param signature |
||||
* the type signature of this local variable. May be |
||||
* <tt>null</tt> if the local variable type does not use generic |
||||
* types. |
||||
* @param start |
||||
* the first instruction corresponding to the scope of this local |
||||
* variable (inclusive). |
||||
* @param end |
||||
* the last instruction corresponding to the scope of this local |
||||
* variable (exclusive). |
||||
* @param index |
||||
* the local variable's index. |
||||
* @throws IllegalArgumentException |
||||
* if one of the labels has not already been visited by this |
||||
* visitor (by the {@link #visitLabel visitLabel} method). |
||||
*/ |
||||
public void visitLocalVariable(String name, String desc, String signature, |
||||
Label start, Label end, int index) { |
||||
if (mv != null) { |
||||
mv.visitLocalVariable(name, desc, signature, start, end, index); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 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. |
||||
* |
||||
* @param line |
||||
* a line number. This number refers to the source file from |
||||
* which the class was compiled. |
||||
* @param start |
||||
* the first instruction corresponding to this line number. |
||||
* @throws IllegalArgumentException |
||||
* if <tt>start</tt> has not already been visited by this |
||||
* visitor (by the {@link #visitLabel visitLabel} method). |
||||
*/ |
||||
public void visitLineNumber(int line, Label start) { |
||||
if (mv != null) { |
||||
mv.visitLineNumber(line, start); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits the maximum stack size and the maximum number of local variables |
||||
* of the method. |
||||
* |
||||
* @param maxStack |
||||
* maximum stack size of the method. |
||||
* @param maxLocals |
||||
* maximum number of local variables for the method. |
||||
*/ |
||||
public void visitMaxs(int maxStack, int maxLocals) { |
||||
if (mv != null) { |
||||
mv.visitMaxs(maxStack, maxLocals); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits the end of the method. This method, which is the last one to be |
||||
* called, is used to inform the visitor that all the annotations and |
||||
* attributes of the method have been visited. |
||||
*/ |
||||
public void visitEnd() { |
||||
if (mv != null) { |
||||
mv.visitEnd(); |
||||
} |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,190 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* A visitor to visit a Java module. The methods of this class must be called in |
||||
* the following order: <tt>visitMainClass</tt> | ( <tt>visitPackage</tt> | |
||||
* <tt>visitRequire</tt> | <tt>visitExport</tt> | <tt>visitOpen</tt> | |
||||
* <tt>visitUse</tt> | <tt>visitProvide</tt> )* <tt>visitEnd</tt>. |
||||
* |
||||
* The methods {@link #visitRequire(String, int, String)}, {@link #visitExport(String, int, String...)}, |
||||
* {@link #visitOpen(String, int, String...)} and {@link #visitPackage(String)} |
||||
* take as parameter a package name or a module name. Unlike the other names which are internal names |
||||
* (names separated by slash), module and package names are qualified names (names separated by dot). |
||||
* |
||||
* @author Remi Forax |
||||
*/ |
||||
public abstract class ModuleVisitor { |
||||
/** |
||||
* The ASM API version implemented by this visitor. The value of this field |
||||
* must be {@link Opcodes#ASM6}. |
||||
*/ |
||||
protected final int api; |
||||
|
||||
/** |
||||
* The module visitor to which this visitor must delegate method calls. May |
||||
* be null. |
||||
*/ |
||||
protected ModuleVisitor mv; |
||||
|
||||
/** |
||||
* Constructs a new {@link ModuleVisitor}. |
||||
* |
||||
* @param api |
||||
* the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}. |
||||
*/ |
||||
public ModuleVisitor(final int api) { |
||||
this(api, null); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a new {@link ModuleVisitor}. |
||||
* |
||||
* @param api |
||||
* the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}. |
||||
* @param mv |
||||
* the module visitor to which this visitor must delegate method |
||||
* calls. May be null. |
||||
*/ |
||||
public ModuleVisitor(final int api, final ModuleVisitor mv) { |
||||
if (api != Opcodes.ASM6) { |
||||
throw new IllegalArgumentException(); |
||||
} |
||||
this.api = api; |
||||
this.mv = mv; |
||||
} |
||||
|
||||
/** |
||||
* Visit the main class of the current module. |
||||
* |
||||
* @param mainClass the internal name of the main class of the current module. |
||||
*/ |
||||
public void visitMainClass(String mainClass) { |
||||
if (mv != null) { |
||||
mv.visitMainClass(mainClass); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visit a package of the current module. |
||||
* |
||||
* @param packaze the qualified name of a package. |
||||
*/ |
||||
public void visitPackage(String packaze) { |
||||
if (mv != null) { |
||||
mv.visitPackage(packaze); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits a dependence of the current module. |
||||
* |
||||
* @param module the qualified name of the dependence. |
||||
* @param access the access flag of the dependence among |
||||
* ACC_TRANSITIVE, ACC_STATIC_PHASE, ACC_SYNTHETIC |
||||
* and ACC_MANDATED. |
||||
* @param version the module version at compile time or null. |
||||
*/ |
||||
public void visitRequire(String module, int access, String version) { |
||||
if (mv != null) { |
||||
mv.visitRequire(module, access, version); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visit an exported package of the current module. |
||||
* |
||||
* @param packaze the qualified name of the exported package. |
||||
* @param access the access flag of the exported package, |
||||
* valid values are among {@code ACC_SYNTHETIC} and |
||||
* {@code ACC_MANDATED}. |
||||
* @param modules the qualified names of the modules that can access to |
||||
* the public classes of the exported package or |
||||
* <tt>null</tt>. |
||||
*/ |
||||
public void visitExport(String packaze, int access, String... modules) { |
||||
if (mv != null) { |
||||
mv.visitExport(packaze, access, modules); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visit an open package of the current module. |
||||
* |
||||
* @param packaze the qualified name of the opened package. |
||||
* @param access the access flag of the opened package, |
||||
* valid values are among {@code ACC_SYNTHETIC} and |
||||
* {@code ACC_MANDATED}. |
||||
* @param modules the qualified names of the modules that can use deep |
||||
* reflection to the classes of the open package or |
||||
* <tt>null</tt>. |
||||
*/ |
||||
public void visitOpen(String packaze, int access, String... modules) { |
||||
if (mv != null) { |
||||
mv.visitOpen(packaze, access, modules); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visit a service used by the current module. |
||||
* The name must be the internal name of an interface or a class. |
||||
* |
||||
* @param service the internal name of the service. |
||||
*/ |
||||
public void visitUse(String service) { |
||||
if (mv != null) { |
||||
mv.visitUse(service); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visit an implementation of a service. |
||||
* |
||||
* @param service the internal name of the service |
||||
* @param providers the internal names of the implementations |
||||
* of the service (there is at least one provider). |
||||
*/ |
||||
public void visitProvide(String service, String... providers) { |
||||
if (mv != null) { |
||||
mv.visitProvide(service, providers); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits the end of the module. This method, which is the last one to be |
||||
* called, is used to inform the visitor that everything have been visited. |
||||
*/ |
||||
public void visitEnd() { |
||||
if (mv != null) { |
||||
mv.visitEnd(); |
||||
} |
||||
} |
||||
} |
@ -1,293 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* @author Remi Forax |
||||
*/ |
||||
final class ModuleWriter extends ModuleVisitor { |
||||
/** |
||||
* The class writer to which this Module attribute must be added. |
||||
*/ |
||||
private final ClassWriter cw; |
||||
|
||||
/** |
||||
* size in byte of the Module attribute. |
||||
*/ |
||||
int size; |
||||
|
||||
/** |
||||
* Number of attributes associated with the current module |
||||
* (Version, ConcealPackages, etc) |
||||
*/ |
||||
int attributeCount; |
||||
|
||||
/** |
||||
* Size in bytes of the attributes associated with the current module |
||||
*/ |
||||
int attributesSize; |
||||
|
||||
/** |
||||
* module name index in the constant pool |
||||
*/ |
||||
private final int name; |
||||
|
||||
/** |
||||
* module access flags |
||||
*/ |
||||
private final int access; |
||||
|
||||
/** |
||||
* module version index in the constant pool or 0 |
||||
*/ |
||||
private final int version; |
||||
|
||||
/** |
||||
* module main class index in the constant pool or 0 |
||||
*/ |
||||
private int mainClass; |
||||
|
||||
/** |
||||
* number of packages |
||||
*/ |
||||
private int packageCount; |
||||
|
||||
/** |
||||
* The packages in bytecode form. This byte vector only contains |
||||
* the items themselves, the number of items is store in packageCount |
||||
*/ |
||||
private ByteVector packages; |
||||
|
||||
/** |
||||
* number of requires items |
||||
*/ |
||||
private int requireCount; |
||||
|
||||
/** |
||||
* The requires items in bytecode form. This byte vector only contains |
||||
* the items themselves, the number of items is store in requireCount |
||||
*/ |
||||
private ByteVector requires; |
||||
|
||||
/** |
||||
* number of exports items |
||||
*/ |
||||
private int exportCount; |
||||
|
||||
/** |
||||
* The exports items in bytecode form. This byte vector only contains |
||||
* the items themselves, the number of items is store in exportCount |
||||
*/ |
||||
private ByteVector exports; |
||||
|
||||
/** |
||||
* number of opens items |
||||
*/ |
||||
private int openCount; |
||||
|
||||
/** |
||||
* The opens items in bytecode form. This byte vector only contains |
||||
* the items themselves, the number of items is store in openCount |
||||
*/ |
||||
private ByteVector opens; |
||||
|
||||
/** |
||||
* number of uses items |
||||
*/ |
||||
private int useCount; |
||||
|
||||
/** |
||||
* The uses items in bytecode form. This byte vector only contains |
||||
* the items themselves, the number of items is store in useCount |
||||
*/ |
||||
private ByteVector uses; |
||||
|
||||
/** |
||||
* number of provides items |
||||
*/ |
||||
private int provideCount; |
||||
|
||||
/** |
||||
* The uses provides in bytecode form. This byte vector only contains |
||||
* the items themselves, the number of items is store in provideCount |
||||
*/ |
||||
private ByteVector provides; |
||||
|
||||
ModuleWriter(final ClassWriter cw, final int name, |
||||
final int access, final int version) { |
||||
super(Opcodes.ASM6); |
||||
this.cw = cw; |
||||
this.size = 16; // name + access + version + 5 counts
|
||||
this.name = name; |
||||
this.access = access; |
||||
this.version = version; |
||||
} |
||||
|
||||
@Override |
||||
public void visitMainClass(String mainClass) { |
||||
if (this.mainClass == 0) { // protect against several calls to visitMainClass
|
||||
cw.newUTF8("ModuleMainClass"); |
||||
attributeCount++; |
||||
attributesSize += 8; |
||||
} |
||||
this.mainClass = cw.newClass(mainClass); |
||||
} |
||||
|
||||
@Override |
||||
public void visitPackage(String packaze) { |
||||
if (packages == null) { |
||||
// protect against several calls to visitPackage
|
||||
cw.newUTF8("ModulePackages"); |
||||
packages = new ByteVector(); |
||||
attributeCount++; |
||||
attributesSize += 8; |
||||
} |
||||
packages.putShort(cw.newPackage(packaze)); |
||||
packageCount++; |
||||
attributesSize += 2; |
||||
} |
||||
|
||||
@Override |
||||
public void visitRequire(String module, int access, String version) { |
||||
if (requires == null) { |
||||
requires = new ByteVector(); |
||||
} |
||||
requires.putShort(cw.newModule(module)) |
||||
.putShort(access) |
||||
.putShort(version == null? 0: cw.newUTF8(version)); |
||||
requireCount++; |
||||
size += 6; |
||||
} |
||||
|
||||
@Override |
||||
public void visitExport(String packaze, int access, String... modules) { |
||||
if (exports == null) { |
||||
exports = new ByteVector(); |
||||
} |
||||
exports.putShort(cw.newPackage(packaze)).putShort(access); |
||||
if (modules == null) { |
||||
exports.putShort(0); |
||||
size += 6; |
||||
} else { |
||||
exports.putShort(modules.length); |
||||
for(String module: modules) { |
||||
exports.putShort(cw.newModule(module)); |
||||
} |
||||
size += 6 + 2 * modules.length; |
||||
} |
||||
exportCount++; |
||||
} |
||||
|
||||
@Override |
||||
public void visitOpen(String packaze, int access, String... modules) { |
||||
if (opens == null) { |
||||
opens = new ByteVector(); |
||||
} |
||||
opens.putShort(cw.newPackage(packaze)).putShort(access); |
||||
if (modules == null) { |
||||
opens.putShort(0); |
||||
size += 6; |
||||
} else { |
||||
opens.putShort(modules.length); |
||||
for(String module: modules) { |
||||
opens.putShort(cw.newModule(module)); |
||||
} |
||||
size += 6 + 2 * modules.length; |
||||
} |
||||
openCount++; |
||||
} |
||||
|
||||
@Override |
||||
public void visitUse(String service) { |
||||
if (uses == null) { |
||||
uses = new ByteVector(); |
||||
} |
||||
uses.putShort(cw.newClass(service)); |
||||
useCount++; |
||||
size += 2; |
||||
} |
||||
|
||||
@Override |
||||
public void visitProvide(String service, String... providers) { |
||||
if (provides == null) { |
||||
provides = new ByteVector(); |
||||
} |
||||
provides.putShort(cw.newClass(service)); |
||||
provides.putShort(providers.length); |
||||
for(String provider: providers) { |
||||
provides.putShort(cw.newClass(provider)); |
||||
} |
||||
provideCount++; |
||||
size += 4 + 2 * providers.length; |
||||
} |
||||
|
||||
@Override |
||||
public void visitEnd() { |
||||
// empty
|
||||
} |
||||
|
||||
void putAttributes(ByteVector out) { |
||||
if (mainClass != 0) { |
||||
out.putShort(cw.newUTF8("ModuleMainClass")).putInt(2).putShort(mainClass); |
||||
} |
||||
if (packages != null) { |
||||
out.putShort(cw.newUTF8("ModulePackages")) |
||||
.putInt(2 + 2 * packageCount) |
||||
.putShort(packageCount) |
||||
.putByteArray(packages.data, 0, packages.length); |
||||
} |
||||
} |
||||
|
||||
void put(ByteVector out) { |
||||
out.putInt(size); |
||||
out.putShort(name).putShort(access).putShort(version); |
||||
out.putShort(requireCount); |
||||
if (requires != null) { |
||||
out.putByteArray(requires.data, 0, requires.length); |
||||
} |
||||
out.putShort(exportCount); |
||||
if (exports != null) { |
||||
out.putByteArray(exports.data, 0, exports.length); |
||||
} |
||||
out.putShort(openCount); |
||||
if (opens != null) { |
||||
out.putByteArray(opens.data, 0, opens.length); |
||||
} |
||||
out.putShort(useCount); |
||||
if (uses != null) { |
||||
out.putByteArray(uses.data, 0, uses.length); |
||||
} |
||||
out.putShort(provideCount); |
||||
if (provides != null) { |
||||
out.putByteArray(provides.data, 0, provides.length); |
||||
} |
||||
} |
||||
} |
@ -1,372 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
/** |
||||
* Defines the JVM opcodes, access flags and array type codes. This interface
|
||||
* does not define all the JVM opcodes because some opcodes are automatically |
||||
* handled. For example, the xLOAD and xSTORE opcodes are automatically replaced |
||||
* by xLOAD_n and xSTORE_n opcodes when possible. The xLOAD_n and xSTORE_n |
||||
* opcodes are therefore not defined in this interface. Likewise for LDC, |
||||
* automatically replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and |
||||
* JSR_W. |
||||
* |
||||
* @author Eric Bruneton |
||||
* @author Eugene Kuleshov |
||||
*/ |
||||
public interface Opcodes { |
||||
|
||||
// ASM API versions
|
||||
|
||||
int ASM4 = 4 << 16 | 0 << 8 | 0; |
||||
int ASM5 = 5 << 16 | 0 << 8 | 0; |
||||
int ASM6 = 6 << 16 | 0 << 8 | 0; |
||||
|
||||
// versions
|
||||
|
||||
int V1_1 = 3 << 16 | 45; |
||||
int V1_2 = 0 << 16 | 46; |
||||
int V1_3 = 0 << 16 | 47; |
||||
int V1_4 = 0 << 16 | 48; |
||||
int V1_5 = 0 << 16 | 49; |
||||
int V1_6 = 0 << 16 | 50; |
||||
int V1_7 = 0 << 16 | 51; |
||||
int V1_8 = 0 << 16 | 52; |
||||
int V9 = 0 << 16 | 53; |
||||
|
||||
// access flags
|
||||
|
||||
int ACC_PUBLIC = 0x0001; // class, field, method
|
||||
int ACC_PRIVATE = 0x0002; // class, field, method
|
||||
int ACC_PROTECTED = 0x0004; // class, field, method
|
||||
int ACC_STATIC = 0x0008; // field, method
|
||||
int ACC_FINAL = 0x0010; // class, field, method, parameter
|
||||
int ACC_SUPER = 0x0020; // class
|
||||
int ACC_SYNCHRONIZED = 0x0020; // method
|
||||
int ACC_OPEN = 0x0020; // module
|
||||
int ACC_TRANSITIVE = 0x0020; // module requires
|
||||
int ACC_VOLATILE = 0x0040; // field
|
||||
int ACC_BRIDGE = 0x0040; // method
|
||||
int ACC_STATIC_PHASE = 0x0040; // module requires
|
||||
int ACC_VARARGS = 0x0080; // method
|
||||
int ACC_TRANSIENT = 0x0080; // field
|
||||
int ACC_NATIVE = 0x0100; // method
|
||||
int ACC_INTERFACE = 0x0200; // class
|
||||
int ACC_ABSTRACT = 0x0400; // class, method
|
||||
int ACC_STRICT = 0x0800; // method
|
||||
int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter, module *
|
||||
int ACC_ANNOTATION = 0x2000; // class
|
||||
int ACC_ENUM = 0x4000; // class(?) field inner
|
||||
int ACC_MANDATED = 0x8000; // parameter, module, module *
|
||||
int ACC_MODULE = 0x8000; // class
|
||||
|
||||
|
||||
// ASM specific pseudo access flags
|
||||
|
||||
int ACC_DEPRECATED = 0x20000; // class, field, method
|
||||
|
||||
// types for NEWARRAY
|
||||
|
||||
int T_BOOLEAN = 4; |
||||
int T_CHAR = 5; |
||||
int T_FLOAT = 6; |
||||
int T_DOUBLE = 7; |
||||
int T_BYTE = 8; |
||||
int T_SHORT = 9; |
||||
int T_INT = 10; |
||||
int T_LONG = 11; |
||||
|
||||
// tags for Handle
|
||||
|
||||
int H_GETFIELD = 1; |
||||
int H_GETSTATIC = 2; |
||||
int H_PUTFIELD = 3; |
||||
int H_PUTSTATIC = 4; |
||||
int H_INVOKEVIRTUAL = 5; |
||||
int H_INVOKESTATIC = 6; |
||||
int H_INVOKESPECIAL = 7; |
||||
int H_NEWINVOKESPECIAL = 8; |
||||
int H_INVOKEINTERFACE = 9; |
||||
|
||||
// stack map frame types
|
||||
|
||||
/** |
||||
* Represents an expanded frame. See {@link ClassReader#EXPAND_FRAMES}. |
||||
*/ |
||||
int F_NEW = -1; |
||||
|
||||
/** |
||||
* Represents a compressed frame with complete frame data. |
||||
*/ |
||||
int F_FULL = 0; |
||||
|
||||
/** |
||||
* Represents a compressed frame where locals are the same as the locals in |
||||
* the previous frame, except that additional 1-3 locals are defined, and |
||||
* with an empty stack. |
||||
*/ |
||||
int F_APPEND = 1; |
||||
|
||||
/** |
||||
* Represents a compressed frame where locals are the same as the locals in |
||||
* the previous frame, except that the last 1-3 locals are absent and with |
||||
* an empty stack. |
||||
*/ |
||||
int F_CHOP = 2; |
||||
|
||||
/** |
||||
* Represents a compressed frame with exactly the same locals as the |
||||
* previous frame and with an empty stack. |
||||
*/ |
||||
int F_SAME = 3; |
||||
|
||||
/** |
||||
* Represents a compressed frame with exactly the same locals as the |
||||
* previous frame and with a single value on the stack. |
||||
*/ |
||||
int F_SAME1 = 4; |
||||
|
||||
// Do not try to change the following code to use auto-boxing,
|
||||
// these values are compared by reference and not by value
|
||||
// The constructor of Integer was deprecated in 9
|
||||
// but we are stuck with it by backward compatibility
|
||||
@SuppressWarnings("deprecation") Integer TOP = new Integer(0); |
||||
@SuppressWarnings("deprecation") Integer INTEGER = new Integer(1); |
||||
@SuppressWarnings("deprecation") Integer FLOAT = new Integer(2); |
||||
@SuppressWarnings("deprecation") Integer DOUBLE = new Integer(3); |
||||
@SuppressWarnings("deprecation") Integer LONG = new Integer(4); |
||||
@SuppressWarnings("deprecation") Integer NULL = new Integer(5); |
||||
@SuppressWarnings("deprecation") Integer UNINITIALIZED_THIS = new Integer(6); |
||||
|
||||
// opcodes // visit method (- = idem)
|
||||
|
||||
int NOP = 0; // visitInsn
|
||||
int ACONST_NULL = 1; // -
|
||||
int ICONST_M1 = 2; // -
|
||||
int ICONST_0 = 3; // -
|
||||
int ICONST_1 = 4; // -
|
||||
int ICONST_2 = 5; // -
|
||||
int ICONST_3 = 6; // -
|
||||
int ICONST_4 = 7; // -
|
||||
int ICONST_5 = 8; // -
|
||||
int LCONST_0 = 9; // -
|
||||
int LCONST_1 = 10; // -
|
||||
int FCONST_0 = 11; // -
|
||||
int FCONST_1 = 12; // -
|
||||
int FCONST_2 = 13; // -
|
||||
int DCONST_0 = 14; // -
|
||||
int DCONST_1 = 15; // -
|
||||
int BIPUSH = 16; // visitIntInsn
|
||||
int SIPUSH = 17; // -
|
||||
int LDC = 18; // visitLdcInsn
|
||||
// int LDC_W = 19; // -
|
||||
// int LDC2_W = 20; // -
|
||||
int ILOAD = 21; // visitVarInsn
|
||||
int LLOAD = 22; // -
|
||||
int FLOAD = 23; // -
|
||||
int DLOAD = 24; // -
|
||||
int ALOAD = 25; // -
|
||||
// int ILOAD_0 = 26; // -
|
||||
// int ILOAD_1 = 27; // -
|
||||
// int ILOAD_2 = 28; // -
|
||||
// int ILOAD_3 = 29; // -
|
||||
// int LLOAD_0 = 30; // -
|
||||
// int LLOAD_1 = 31; // -
|
||||
// int LLOAD_2 = 32; // -
|
||||
// int LLOAD_3 = 33; // -
|
||||
// int FLOAD_0 = 34; // -
|
||||
// int FLOAD_1 = 35; // -
|
||||
// int FLOAD_2 = 36; // -
|
||||
// int FLOAD_3 = 37; // -
|
||||
// int DLOAD_0 = 38; // -
|
||||
// int DLOAD_1 = 39; // -
|
||||
// int DLOAD_2 = 40; // -
|
||||
// int DLOAD_3 = 41; // -
|
||||
// int ALOAD_0 = 42; // -
|
||||
// int ALOAD_1 = 43; // -
|
||||
// int ALOAD_2 = 44; // -
|
||||
// int ALOAD_3 = 45; // -
|
||||
int IALOAD = 46; // visitInsn
|
||||
int LALOAD = 47; // -
|
||||
int FALOAD = 48; // -
|
||||
int DALOAD = 49; // -
|
||||
int AALOAD = 50; // -
|
||||
int BALOAD = 51; // -
|
||||
int CALOAD = 52; // -
|
||||
int SALOAD = 53; // -
|
||||
int ISTORE = 54; // visitVarInsn
|
||||
int LSTORE = 55; // -
|
||||
int FSTORE = 56; // -
|
||||
int DSTORE = 57; // -
|
||||
int ASTORE = 58; // -
|
||||
// int ISTORE_0 = 59; // -
|
||||
// int ISTORE_1 = 60; // -
|
||||
// int ISTORE_2 = 61; // -
|
||||
// int ISTORE_3 = 62; // -
|
||||
// int LSTORE_0 = 63; // -
|
||||
// int LSTORE_1 = 64; // -
|
||||
// int LSTORE_2 = 65; // -
|
||||
// int LSTORE_3 = 66; // -
|
||||
// int FSTORE_0 = 67; // -
|
||||
// int FSTORE_1 = 68; // -
|
||||
// int FSTORE_2 = 69; // -
|
||||
// int FSTORE_3 = 70; // -
|
||||
// int DSTORE_0 = 71; // -
|
||||
// int DSTORE_1 = 72; // -
|
||||
// int DSTORE_2 = 73; // -
|
||||
// int DSTORE_3 = 74; // -
|
||||
// int ASTORE_0 = 75; // -
|
||||
// int ASTORE_1 = 76; // -
|
||||
// int ASTORE_2 = 77; // -
|
||||
// int ASTORE_3 = 78; // -
|
||||
int IASTORE = 79; // visitInsn
|
||||
int LASTORE = 80; // -
|
||||
int FASTORE = 81; // -
|
||||
int DASTORE = 82; // -
|
||||
int AASTORE = 83; // -
|
||||
int BASTORE = 84; // -
|
||||
int CASTORE = 85; // -
|
||||
int SASTORE = 86; // -
|
||||
int POP = 87; // -
|
||||
int POP2 = 88; // -
|
||||
int DUP = 89; // -
|
||||
int DUP_X1 = 90; // -
|
||||
int DUP_X2 = 91; // -
|
||||
int DUP2 = 92; // -
|
||||
int DUP2_X1 = 93; // -
|
||||
int DUP2_X2 = 94; // -
|
||||
int SWAP = 95; // -
|
||||
int IADD = 96; // -
|
||||
int LADD = 97; // -
|
||||
int FADD = 98; // -
|
||||
int DADD = 99; // -
|
||||
int ISUB = 100; // -
|
||||
int LSUB = 101; // -
|
||||
int FSUB = 102; // -
|
||||
int DSUB = 103; // -
|
||||
int IMUL = 104; // -
|
||||
int LMUL = 105; // -
|
||||
int FMUL = 106; // -
|
||||
int DMUL = 107; // -
|
||||
int IDIV = 108; // -
|
||||
int LDIV = 109; // -
|
||||
int FDIV = 110; // -
|
||||
int DDIV = 111; // -
|
||||
int IREM = 112; // -
|
||||
int LREM = 113; // -
|
||||
int FREM = 114; // -
|
||||
int DREM = 115; // -
|
||||
int INEG = 116; // -
|
||||
int LNEG = 117; // -
|
||||
int FNEG = 118; // -
|
||||
int DNEG = 119; // -
|
||||
int ISHL = 120; // -
|
||||
int LSHL = 121; // -
|
||||
int ISHR = 122; // -
|
||||
int LSHR = 123; // -
|
||||
int IUSHR = 124; // -
|
||||
int LUSHR = 125; // -
|
||||
int IAND = 126; // -
|
||||
int LAND = 127; // -
|
||||
int IOR = 128; // -
|
||||
int LOR = 129; // -
|
||||
int IXOR = 130; // -
|
||||
int LXOR = 131; // -
|
||||
int IINC = 132; // visitIincInsn
|
||||
int I2L = 133; // visitInsn
|
||||
int I2F = 134; // -
|
||||
int I2D = 135; // -
|
||||
int L2I = 136; // -
|
||||
int L2F = 137; // -
|
||||
int L2D = 138; // -
|
||||
int F2I = 139; // -
|
||||
int F2L = 140; // -
|
||||
int F2D = 141; // -
|
||||
int D2I = 142; // -
|
||||
int D2L = 143; // -
|
||||
int D2F = 144; // -
|
||||
int I2B = 145; // -
|
||||
int I2C = 146; // -
|
||||
int I2S = 147; // -
|
||||
int LCMP = 148; // -
|
||||
int FCMPL = 149; // -
|
||||
int FCMPG = 150; // -
|
||||
int DCMPL = 151; // -
|
||||
int DCMPG = 152; // -
|
||||
int IFEQ = 153; // visitJumpInsn
|
||||
int IFNE = 154; // -
|
||||
int IFLT = 155; // -
|
||||
int IFGE = 156; // -
|
||||
int IFGT = 157; // -
|
||||
int IFLE = 158; // -
|
||||
int IF_ICMPEQ = 159; // -
|
||||
int IF_ICMPNE = 160; // -
|
||||
int IF_ICMPLT = 161; // -
|
||||
int IF_ICMPGE = 162; // -
|
||||
int IF_ICMPGT = 163; // -
|
||||
int IF_ICMPLE = 164; // -
|
||||
int IF_ACMPEQ = 165; // -
|
||||
int IF_ACMPNE = 166; // -
|
||||
int GOTO = 167; // -
|
||||
int JSR = 168; // -
|
||||
int RET = 169; // visitVarInsn
|
||||
int TABLESWITCH = 170; // visiTableSwitchInsn
|
||||
int LOOKUPSWITCH = 171; // visitLookupSwitch
|
||||
int IRETURN = 172; // visitInsn
|
||||
int LRETURN = 173; // -
|
||||
int FRETURN = 174; // -
|
||||
int DRETURN = 175; // -
|
||||
int ARETURN = 176; // -
|
||||
int RETURN = 177; // -
|
||||
int GETSTATIC = 178; // visitFieldInsn
|
||||
int PUTSTATIC = 179; // -
|
||||
int GETFIELD = 180; // -
|
||||
int PUTFIELD = 181; // -
|
||||
int INVOKEVIRTUAL = 182; // visitMethodInsn
|
||||
int INVOKESPECIAL = 183; // -
|
||||
int INVOKESTATIC = 184; // -
|
||||
int INVOKEINTERFACE = 185; // -
|
||||
int INVOKEDYNAMIC = 186; // visitInvokeDynamicInsn
|
||||
int NEW = 187; // visitTypeInsn
|
||||
int NEWARRAY = 188; // visitIntInsn
|
||||
int ANEWARRAY = 189; // visitTypeInsn
|
||||
int ARRAYLENGTH = 190; // visitInsn
|
||||
int ATHROW = 191; // -
|
||||
int CHECKCAST = 192; // visitTypeInsn
|
||||
int INSTANCEOF = 193; // -
|
||||
int MONITORENTER = 194; // visitInsn
|
||||
int MONITOREXIT = 195; // -
|
||||
// int WIDE = 196; // NOT VISITED
|
||||
int MULTIANEWARRAY = 197; // visitMultiANewArrayInsn
|
||||
int IFNULL = 198; // visitJumpInsn
|
||||
int IFNONNULL = 199; // -
|
||||
// int GOTO_W = 200; // -
|
||||
// int JSR_W = 201; // -
|
||||
} |
@ -1,905 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm; |
||||
|
||||
import java.lang.reflect.Constructor; |
||||
import java.lang.reflect.Method; |
||||
|
||||
/** |
||||
* A Java field or method type. This class can be used to make it easier to |
||||
* manipulate type and method descriptors. |
||||
* |
||||
* @author Eric Bruneton |
||||
* @author Chris Nokleberg |
||||
*/ |
||||
public class Type { |
||||
|
||||
/** |
||||
* The sort of the <tt>void</tt> type. See {@link #getSort getSort}. |
||||
*/ |
||||
public static final int VOID = 0; |
||||
|
||||
/** |
||||
* The sort of the <tt>boolean</tt> type. See {@link #getSort getSort}. |
||||
*/ |
||||
public static final int BOOLEAN = 1; |
||||
|
||||
/** |
||||
* The sort of the <tt>char</tt> type. See {@link #getSort getSort}. |
||||
*/ |
||||
public static final int CHAR = 2; |
||||
|
||||
/** |
||||
* The sort of the <tt>byte</tt> type. See {@link #getSort getSort}. |
||||
*/ |
||||
public static final int BYTE = 3; |
||||
|
||||
/** |
||||
* The sort of the <tt>short</tt> type. See {@link #getSort getSort}. |
||||
*/ |
||||
public static final int SHORT = 4; |
||||
|
||||
/** |
||||
* The sort of the <tt>int</tt> type. See {@link #getSort getSort}. |
||||
*/ |
||||
public static final int INT = 5; |
||||
|
||||
/** |
||||
* The sort of the <tt>float</tt> type. See {@link #getSort getSort}. |
||||
*/ |
||||
public static final int FLOAT = 6; |
||||
|
||||
/** |
||||
* The sort of the <tt>long</tt> type. See {@link #getSort getSort}. |
||||
*/ |
||||
public static final int LONG = 7; |
||||
|
||||
/** |
||||
* The sort of the <tt>double</tt> type. See {@link #getSort getSort}. |
||||
*/ |
||||
public static final int DOUBLE = 8; |
||||
|
||||
/** |
||||
* The sort of array reference types. See {@link #getSort getSort}. |
||||
*/ |
||||
public static final int ARRAY = 9; |
||||
|
||||
/** |
||||
* The sort of object reference types. See {@link #getSort getSort}. |
||||
*/ |
||||
public static final int OBJECT = 10; |
||||
|
||||
/** |
||||
* The sort of method types. See {@link #getSort getSort}. |
||||
*/ |
||||
public static final int METHOD = 11; |
||||
|
||||
/** |
||||
* The <tt>void</tt> type. |
||||
*/ |
||||
public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24) |
||||
| (5 << 16) | (0 << 8) | 0, 1); |
||||
|
||||
/** |
||||
* The <tt>boolean</tt> type. |
||||
*/ |
||||
public static final Type BOOLEAN_TYPE = new Type(BOOLEAN, null, ('Z' << 24) |
||||
| (0 << 16) | (5 << 8) | 1, 1); |
||||
|
||||
/** |
||||
* The <tt>char</tt> type. |
||||
*/ |
||||
public static final Type CHAR_TYPE = new Type(CHAR, null, ('C' << 24) |
||||
| (0 << 16) | (6 << 8) | 1, 1); |
||||
|
||||
/** |
||||
* The <tt>byte</tt> type. |
||||
*/ |
||||
public static final Type BYTE_TYPE = new Type(BYTE, null, ('B' << 24) |
||||
| (0 << 16) | (5 << 8) | 1, 1); |
||||
|
||||
/** |
||||
* The <tt>short</tt> type. |
||||
*/ |
||||
public static final Type SHORT_TYPE = new Type(SHORT, null, ('S' << 24) |
||||
| (0 << 16) | (7 << 8) | 1, 1); |
||||
|
||||
/** |
||||
* The <tt>int</tt> type. |
||||
*/ |
||||
public static final Type INT_TYPE = new Type(INT, null, ('I' << 24) |
||||
| (0 << 16) | (0 << 8) | 1, 1); |
||||
|
||||
/** |
||||
* The <tt>float</tt> type. |
||||
*/ |
||||
public static final Type FLOAT_TYPE = new Type(FLOAT, null, ('F' << 24) |
||||
| (2 << 16) | (2 << 8) | 1, 1); |
||||
|
||||
/** |
||||
* The <tt>long</tt> type. |
||||
*/ |
||||
public static final Type LONG_TYPE = new Type(LONG, null, ('J' << 24) |
||||
| (1 << 16) | (1 << 8) | 2, 1); |
||||
|
||||
/** |
||||
* The <tt>double</tt> type. |
||||
*/ |
||||
public static final Type DOUBLE_TYPE = new Type(DOUBLE, null, ('D' << 24) |
||||
| (3 << 16) | (3 << 8) | 2, 1); |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Fields
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* The sort of this Java type. |
||||
*/ |
||||
private final int sort; |
||||
|
||||
/** |
||||
* A buffer containing the internal name of this Java type. This field is |
||||
* only used for reference types. |
||||
*/ |
||||
private final char[] buf; |
||||
|
||||
/** |
||||
* The offset of the internal name of this Java type in {@link #buf buf} or, |
||||
* for primitive types, the size, descriptor and getOpcode offsets for this |
||||
* type (byte 0 contains the size, byte 1 the descriptor, byte 2 the offset |
||||
* for IALOAD or IASTORE, byte 3 the offset for all other instructions). |
||||
*/ |
||||
private final int off; |
||||
|
||||
/** |
||||
* The length of the internal name of this Java type. |
||||
*/ |
||||
private final int len; |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Constructors
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Constructs a reference type. |
||||
* |
||||
* @param sort |
||||
* the sort of the reference type to be constructed. |
||||
* @param buf |
||||
* a buffer containing the descriptor of the previous type. |
||||
* @param off |
||||
* the offset of this descriptor in the previous buffer. |
||||
* @param len |
||||
* the length of this descriptor. |
||||
*/ |
||||
private Type(final int sort, final char[] buf, final int off, final int len) { |
||||
this.sort = sort; |
||||
this.buf = buf; |
||||
this.off = off; |
||||
this.len = len; |
||||
} |
||||
|
||||
/** |
||||
* Returns the Java type corresponding to the given type descriptor. |
||||
* |
||||
* @param typeDescriptor |
||||
* a field or method type descriptor. |
||||
* @return the Java type corresponding to the given type descriptor. |
||||
*/ |
||||
public static Type getType(final String typeDescriptor) { |
||||
return getType(typeDescriptor.toCharArray(), 0); |
||||
} |
||||
|
||||
/** |
||||
* Returns the Java type corresponding to the given internal name. |
||||
* |
||||
* @param internalName |
||||
* an internal name. |
||||
* @return the Java type corresponding to the given internal name. |
||||
*/ |
||||
public static Type getObjectType(final String internalName) { |
||||
char[] buf = internalName.toCharArray(); |
||||
return new Type(buf[0] == '[' ? ARRAY : OBJECT, buf, 0, buf.length); |
||||
} |
||||
|
||||
/** |
||||
* Returns the Java type corresponding to the given method descriptor. |
||||
* Equivalent to <code>Type.getType(methodDescriptor)</code>. |
||||
* |
||||
* @param methodDescriptor |
||||
* a method descriptor. |
||||
* @return the Java type corresponding to the given method descriptor. |
||||
*/ |
||||
public static Type getMethodType(final String methodDescriptor) { |
||||
return getType(methodDescriptor.toCharArray(), 0); |
||||
} |
||||
|
||||
/** |
||||
* Returns the Java method type corresponding to the given argument and |
||||
* return types. |
||||
* |
||||
* @param returnType |
||||
* the return type of the method. |
||||
* @param argumentTypes |
||||
* the argument types of the method. |
||||
* @return the Java type corresponding to the given argument and return |
||||
* types. |
||||
*/ |
||||
public static Type getMethodType(final Type returnType, |
||||
final Type... argumentTypes) { |
||||
return getType(getMethodDescriptor(returnType, argumentTypes)); |
||||
} |
||||
|
||||
/** |
||||
* Returns the Java type corresponding to the given class. |
||||
* |
||||
* @param c |
||||
* a class. |
||||
* @return the Java type corresponding to the given class. |
||||
*/ |
||||
public static Type getType(final Class<?> c) { |
||||
if (c.isPrimitive()) { |
||||
if (c == Integer.TYPE) { |
||||
return INT_TYPE; |
||||
} else if (c == Void.TYPE) { |
||||
return VOID_TYPE; |
||||
} else if (c == Boolean.TYPE) { |
||||
return BOOLEAN_TYPE; |
||||
} else if (c == Byte.TYPE) { |
||||
return BYTE_TYPE; |
||||
} else if (c == Character.TYPE) { |
||||
return CHAR_TYPE; |
||||
} else if (c == Short.TYPE) { |
||||
return SHORT_TYPE; |
||||
} else if (c == Double.TYPE) { |
||||
return DOUBLE_TYPE; |
||||
} else if (c == Float.TYPE) { |
||||
return FLOAT_TYPE; |
||||
} else /* if (c == Long.TYPE) */{ |
||||
return LONG_TYPE; |
||||
} |
||||
} else { |
||||
return getType(getDescriptor(c)); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Returns the Java method type corresponding to the given constructor. |
||||
* |
||||
* @param c |
||||
* a {@link Constructor Constructor} object. |
||||
* @return the Java method type corresponding to the given constructor. |
||||
*/ |
||||
public static Type getType(final Constructor<?> c) { |
||||
return getType(getConstructorDescriptor(c)); |
||||
} |
||||
|
||||
/** |
||||
* Returns the Java method type corresponding to the given method. |
||||
* |
||||
* @param m |
||||
* a {@link Method Method} object. |
||||
* @return the Java method type corresponding to the given method. |
||||
*/ |
||||
public static Type getType(final Method m) { |
||||
return getType(getMethodDescriptor(m)); |
||||
} |
||||
|
||||
/** |
||||
* Returns the Java types corresponding to the argument types of the given |
||||
* method descriptor. |
||||
* |
||||
* @param methodDescriptor |
||||
* a method descriptor. |
||||
* @return the Java types corresponding to the argument types of the given |
||||
* method descriptor. |
||||
*/ |
||||
public static Type[] getArgumentTypes(final String methodDescriptor) { |
||||
char[] buf = methodDescriptor.toCharArray(); |
||||
int off = 1; |
||||
int size = 0; |
||||
while (true) { |
||||
char car = buf[off++]; |
||||
if (car == ')') { |
||||
break; |
||||
} else if (car == 'L') { |
||||
while (buf[off++] != ';') { |
||||
} |
||||
++size; |
||||
} else if (car != '[') { |
||||
++size; |
||||
} |
||||
} |
||||
Type[] args = new Type[size]; |
||||
off = 1; |
||||
size = 0; |
||||
while (buf[off] != ')') { |
||||
args[size] = getType(buf, off); |
||||
off += args[size].len + (args[size].sort == OBJECT ? 2 : 0); |
||||
size += 1; |
||||
} |
||||
return args; |
||||
} |
||||
|
||||
/** |
||||
* Returns the Java types corresponding to the argument types of the given |
||||
* method. |
||||
* |
||||
* @param method |
||||
* a method. |
||||
* @return the Java types corresponding to the argument types of the given |
||||
* method. |
||||
*/ |
||||
public static Type[] getArgumentTypes(final Method method) { |
||||
Class<?>[] classes = method.getParameterTypes(); |
||||
Type[] types = new Type[classes.length]; |
||||
for (int i = classes.length - 1; i >= 0; --i) { |
||||
types[i] = getType(classes[i]); |
||||
} |
||||
return types; |
||||
} |
||||
|
||||
/** |
||||
* Returns the Java type corresponding to the return type of the given |
||||
* method descriptor. |
||||
* |
||||
* @param methodDescriptor |
||||
* a method descriptor. |
||||
* @return the Java type corresponding to the return type of the given |
||||
* method descriptor. |
||||
*/ |
||||
public static Type getReturnType(final String methodDescriptor) { |
||||
char[] buf = methodDescriptor.toCharArray(); |
||||
int off = 1; |
||||
while (true) { |
||||
char car = buf[off++]; |
||||
if (car == ')') { |
||||
return getType(buf, off); |
||||
} else if (car == 'L') { |
||||
while (buf[off++] != ';') { |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Returns the Java type corresponding to the return type of the given |
||||
* method. |
||||
* |
||||
* @param method |
||||
* a method. |
||||
* @return the Java type corresponding to the return type of the given |
||||
* method. |
||||
*/ |
||||
public static Type getReturnType(final Method method) { |
||||
return getType(method.getReturnType()); |
||||
} |
||||
|
||||
/** |
||||
* Computes the size of the arguments and of the return value of a method. |
||||
* |
||||
* @param desc |
||||
* the descriptor of a method. |
||||
* @return the size of the arguments of the method (plus one for the |
||||
* implicit this argument), argSize, and the size of its return |
||||
* value, retSize, packed into a single int i = |
||||
* <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal to |
||||
* <tt>i >> 2</tt>, and retSize to <tt>i & 0x03</tt>). |
||||
*/ |
||||
public static int getArgumentsAndReturnSizes(final String desc) { |
||||
int n = 1; |
||||
int c = 1; |
||||
while (true) { |
||||
char car = desc.charAt(c++); |
||||
if (car == ')') { |
||||
car = desc.charAt(c); |
||||
return n << 2 |
||||
| (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1)); |
||||
} else if (car == 'L') { |
||||
while (desc.charAt(c++) != ';') { |
||||
} |
||||
n += 1; |
||||
} else if (car == '[') { |
||||
while ((car = desc.charAt(c)) == '[') { |
||||
++c; |
||||
} |
||||
if (car == 'D' || car == 'J') { |
||||
n -= 1; |
||||
} |
||||
} else if (car == 'D' || car == 'J') { |
||||
n += 2; |
||||
} else { |
||||
n += 1; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Returns the Java type corresponding to the given type descriptor. For |
||||
* method descriptors, buf is supposed to contain nothing more than the |
||||
* descriptor itself. |
||||
* |
||||
* @param buf |
||||
* a buffer containing a type descriptor. |
||||
* @param off |
||||
* the offset of this descriptor in the previous buffer. |
||||
* @return the Java type corresponding to the given type descriptor. |
||||
*/ |
||||
private static Type getType(final char[] buf, final int off) { |
||||
int len; |
||||
switch (buf[off]) { |
||||
case 'V': |
||||
return VOID_TYPE; |
||||
case 'Z': |
||||
return BOOLEAN_TYPE; |
||||
case 'C': |
||||
return CHAR_TYPE; |
||||
case 'B': |
||||
return BYTE_TYPE; |
||||
case 'S': |
||||
return SHORT_TYPE; |
||||
case 'I': |
||||
return INT_TYPE; |
||||
case 'F': |
||||
return FLOAT_TYPE; |
||||
case 'J': |
||||
return LONG_TYPE; |
||||
case 'D': |
||||
return DOUBLE_TYPE; |
||||
case '[': |
||||
len = 1; |
||||
while (buf[off + len] == '[') { |
||||
++len; |
||||
} |
||||
if (buf[off + len] == 'L') { |
||||
++len; |
||||
while (buf[off + len] != ';') { |
||||
++len; |
||||
} |
||||
} |
||||
return new Type(ARRAY, buf, off, len + 1); |
||||
case 'L': |
||||
len = 1; |
||||
while (buf[off + len] != ';') { |
||||
++len; |
||||
} |
||||
return new Type(OBJECT, buf, off + 1, len - 1); |
||||
// case '(':
|
||||
default: |
||||
return new Type(METHOD, buf, off, buf.length - off); |
||||
} |
||||
} |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Accessors
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Returns the sort of this Java type. |
||||
* |
||||
* @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR}, |
||||
* {@link #BYTE BYTE}, {@link #SHORT SHORT}, {@link #INT INT}, |
||||
* {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE}, |
||||
* {@link #ARRAY ARRAY}, {@link #OBJECT OBJECT} or {@link #METHOD |
||||
* METHOD}. |
||||
*/ |
||||
public int getSort() { |
||||
return sort; |
||||
} |
||||
|
||||
/** |
||||
* Returns the number of dimensions of this array type. This method should |
||||
* only be used for an array type. |
||||
* |
||||
* @return the number of dimensions of this array type. |
||||
*/ |
||||
public int getDimensions() { |
||||
int i = 1; |
||||
while (buf[off + i] == '[') { |
||||
++i; |
||||
} |
||||
return i; |
||||
} |
||||
|
||||
/** |
||||
* Returns the type of the elements of this array type. This method should |
||||
* only be used for an array type. |
||||
* |
||||
* @return Returns the type of the elements of this array type. |
||||
*/ |
||||
public Type getElementType() { |
||||
return getType(buf, off + getDimensions()); |
||||
} |
||||
|
||||
/** |
||||
* Returns the binary name of the class corresponding to this type. This |
||||
* method must not be used on method types. |
||||
* |
||||
* @return the binary name of the class corresponding to this type. |
||||
*/ |
||||
public String getClassName() { |
||||
switch (sort) { |
||||
case VOID: |
||||
return "void"; |
||||
case BOOLEAN: |
||||
return "boolean"; |
||||
case CHAR: |
||||
return "char"; |
||||
case BYTE: |
||||
return "byte"; |
||||
case SHORT: |
||||
return "short"; |
||||
case INT: |
||||
return "int"; |
||||
case FLOAT: |
||||
return "float"; |
||||
case LONG: |
||||
return "long"; |
||||
case DOUBLE: |
||||
return "double"; |
||||
case ARRAY: |
||||
StringBuilder sb = new StringBuilder(getElementType().getClassName()); |
||||
for (int i = getDimensions(); i > 0; --i) { |
||||
sb.append("[]"); |
||||
} |
||||
return sb.toString(); |
||||
case OBJECT: |
||||
return new String(buf, off, len).replace('/', '.'); |
||||
default: |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Returns the internal name of the class corresponding to this object or |
||||
* array type. The internal name of a class is its fully qualified name (as |
||||
* returned by Class.getName(), where '.' are replaced by '/'. This method |
||||
* should only be used for an object or array type. |
||||
* |
||||
* @return the internal name of the class corresponding to this object type. |
||||
*/ |
||||
public String getInternalName() { |
||||
return new String(buf, off, len); |
||||
} |
||||
|
||||
/** |
||||
* Returns the argument types of methods of this type. This method should |
||||
* only be used for method types. |
||||
* |
||||
* @return the argument types of methods of this type. |
||||
*/ |
||||
public Type[] getArgumentTypes() { |
||||
return getArgumentTypes(getDescriptor()); |
||||
} |
||||
|
||||
/** |
||||
* Returns the return type of methods of this type. This method should only |
||||
* be used for method types. |
||||
* |
||||
* @return the return type of methods of this type. |
||||
*/ |
||||
public Type getReturnType() { |
||||
return getReturnType(getDescriptor()); |
||||
} |
||||
|
||||
/** |
||||
* Returns the size of the arguments and of the return value of methods of |
||||
* this type. This method should only be used for method types. |
||||
* |
||||
* @return the size of the arguments (plus one for the implicit this |
||||
* argument), argSize, and the size of the return value, retSize, |
||||
* packed into a single |
||||
* int i = <tt>(argSize << 2) | retSize</tt> |
||||
* (argSize is therefore equal to <tt>i >> 2</tt>, |
||||
* and retSize to <tt>i & 0x03</tt>). |
||||
*/ |
||||
public int getArgumentsAndReturnSizes() { |
||||
return getArgumentsAndReturnSizes(getDescriptor()); |
||||
} |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Conversion to type descriptors
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Returns the descriptor corresponding to this Java type. |
||||
* |
||||
* @return the descriptor corresponding to this Java type. |
||||
*/ |
||||
public String getDescriptor() { |
||||
StringBuilder buf = new StringBuilder(); |
||||
getDescriptor(buf); |
||||
return buf.toString(); |
||||
} |
||||
|
||||
/** |
||||
* Returns the descriptor corresponding to the given argument and return |
||||
* types. |
||||
* |
||||
* @param returnType |
||||
* the return type of the method. |
||||
* @param argumentTypes |
||||
* the argument types of the method. |
||||
* @return the descriptor corresponding to the given argument and return |
||||
* types. |
||||
*/ |
||||
public static String getMethodDescriptor(final Type returnType, |
||||
final Type... argumentTypes) { |
||||
StringBuilder buf = new StringBuilder(); |
||||
buf.append('('); |
||||
for (int i = 0; i < argumentTypes.length; ++i) { |
||||
argumentTypes[i].getDescriptor(buf); |
||||
} |
||||
buf.append(')'); |
||||
returnType.getDescriptor(buf); |
||||
return buf.toString(); |
||||
} |
||||
|
||||
/** |
||||
* Appends the descriptor corresponding to this Java type to the given |
||||
* string buffer. |
||||
* |
||||
* @param buf |
||||
* the string buffer to which the descriptor must be appended. |
||||
*/ |
||||
private void getDescriptor(final StringBuilder buf) { |
||||
if (this.buf == null) { |
||||
// descriptor is in byte 3 of 'off' for primitive types (buf ==
|
||||
// null)
|
||||
buf.append((char) ((off & 0xFF000000) >>> 24)); |
||||
} else if (sort == OBJECT) { |
||||
buf.append('L'); |
||||
buf.append(this.buf, off, len); |
||||
buf.append(';'); |
||||
} else { // sort == ARRAY || sort == METHOD
|
||||
buf.append(this.buf, off, len); |
||||
} |
||||
} |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Direct conversion from classes to type descriptors,
|
||||
// without intermediate Type objects
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Returns the internal name of the given class. The internal name of a |
||||
* class is its fully qualified name, as returned by Class.getName(), where |
||||
* '.' are replaced by '/'. |
||||
* |
||||
* @param c |
||||
* an object or array class. |
||||
* @return the internal name of the given class. |
||||
*/ |
||||
public static String getInternalName(final Class<?> c) { |
||||
return c.getName().replace('.', '/'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the descriptor corresponding to the given Java type. |
||||
* |
||||
* @param c |
||||
* an object class, a primitive class or an array class. |
||||
* @return the descriptor corresponding to the given class. |
||||
*/ |
||||
public static String getDescriptor(final Class<?> c) { |
||||
StringBuilder buf = new StringBuilder(); |
||||
getDescriptor(buf, c); |
||||
return buf.toString(); |
||||
} |
||||
|
||||
/** |
||||
* Returns the descriptor corresponding to the given constructor. |
||||
* |
||||
* @param c |
||||
* a {@link Constructor Constructor} object. |
||||
* @return the descriptor of the given constructor. |
||||
*/ |
||||
public static String getConstructorDescriptor(final Constructor<?> c) { |
||||
Class<?>[] parameters = c.getParameterTypes(); |
||||
StringBuilder buf = new StringBuilder(); |
||||
buf.append('('); |
||||
for (int i = 0; i < parameters.length; ++i) { |
||||
getDescriptor(buf, parameters[i]); |
||||
} |
||||
return buf.append(")V").toString(); |
||||
} |
||||
|
||||
/** |
||||
* Returns the descriptor corresponding to the given method. |
||||
* |
||||
* @param m |
||||
* a {@link Method Method} object. |
||||
* @return the descriptor of the given method. |
||||
*/ |
||||
public static String getMethodDescriptor(final Method m) { |
||||
Class<?>[] parameters = m.getParameterTypes(); |
||||
StringBuilder buf = new StringBuilder(); |
||||
buf.append('('); |
||||
for (int i = 0; i < parameters.length; ++i) { |
||||
getDescriptor(buf, parameters[i]); |
||||
} |
||||
buf.append(')'); |
||||
getDescriptor(buf, m.getReturnType()); |
||||
return buf.toString(); |
||||
} |
||||
|
||||
/** |
||||
* Appends the descriptor of the given class to the given string buffer. |
||||
* |
||||
* @param buf |
||||
* the string buffer to which the descriptor must be appended. |
||||
* @param c |
||||
* the class whose descriptor must be computed. |
||||
*/ |
||||
private static void getDescriptor(final StringBuilder buf, final Class<?> c) { |
||||
Class<?> d = c; |
||||
while (true) { |
||||
if (d.isPrimitive()) { |
||||
char car; |
||||
if (d == Integer.TYPE) { |
||||
car = 'I'; |
||||
} else if (d == Void.TYPE) { |
||||
car = 'V'; |
||||
} else if (d == Boolean.TYPE) { |
||||
car = 'Z'; |
||||
} else if (d == Byte.TYPE) { |
||||
car = 'B'; |
||||
} else if (d == Character.TYPE) { |
||||
car = 'C'; |
||||
} else if (d == Short.TYPE) { |
||||
car = 'S'; |
||||
} else if (d == Double.TYPE) { |
||||
car = 'D'; |
||||
} else if (d == Float.TYPE) { |
||||
car = 'F'; |
||||
} else /* if (d == Long.TYPE) */{ |
||||
car = 'J'; |
||||
} |
||||
buf.append(car); |
||||
return; |
||||
} else if (d.isArray()) { |
||||
buf.append('['); |
||||
d = d.getComponentType(); |
||||
} else { |
||||
buf.append('L'); |
||||
String name = d.getName(); |
||||
int len = name.length(); |
||||
for (int i = 0; i < len; ++i) { |
||||
char car = name.charAt(i); |
||||
buf.append(car == '.' ? '/' : car); |
||||
} |
||||
buf.append(';'); |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Corresponding size and opcodes
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Returns the size of values of this type. This method must not be used for |
||||
* method types. |
||||
* |
||||
* @return the size of values of this type, i.e., 2 for <tt>long</tt> and |
||||
* <tt>double</tt>, 0 for <tt>void</tt> and 1 otherwise. |
||||
*/ |
||||
public int getSize() { |
||||
// the size is in byte 0 of 'off' for primitive types (buf == null)
|
||||
return buf == null ? (off & 0xFF) : 1; |
||||
} |
||||
|
||||
/** |
||||
* Returns a JVM instruction opcode adapted to this Java type. This method |
||||
* must not be used for method types. |
||||
* |
||||
* @param opcode |
||||
* a JVM instruction opcode. This opcode must be one of ILOAD, |
||||
* ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, |
||||
* ISHL, ISHR, IUSHR, IAND, IOR, IXOR and IRETURN. |
||||
* @return an opcode that is similar to the given opcode, but adapted to |
||||
* this Java type. For example, if this type is <tt>float</tt> and |
||||
* <tt>opcode</tt> is IRETURN, this method returns FRETURN. |
||||
*/ |
||||
public int getOpcode(final int opcode) { |
||||
if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) { |
||||
// the offset for IALOAD or IASTORE is in byte 1 of 'off' for
|
||||
// primitive types (buf == null)
|
||||
return opcode + (buf == null ? (off & 0xFF00) >> 8 : 4); |
||||
} else { |
||||
// the offset for other instructions is in byte 2 of 'off' for
|
||||
// primitive types (buf == null)
|
||||
return opcode + (buf == null ? (off & 0xFF0000) >> 16 : 4); |
||||
} |
||||
} |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Equals, hashCode and toString
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Tests if the given object is equal to this type. |
||||
* |
||||
* @param o |
||||
* the object to be compared to this type. |
||||
* @return <tt>true</tt> if the given object is equal to this type. |
||||
*/ |
||||
@Override |
||||
public boolean equals(final Object o) { |
||||
if (this == o) { |
||||
return true; |
||||
} |
||||
if (!(o instanceof Type)) { |
||||
return false; |
||||
} |
||||
Type t = (Type) o; |
||||
if (sort != t.sort) { |
||||
return false; |
||||
} |
||||
if (sort >= ARRAY) { |
||||
if (len != t.len) { |
||||
return false; |
||||
} |
||||
for (int i = off, j = t.off, end = i + len; i < end; i++, j++) { |
||||
if (buf[i] != t.buf[j]) { |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* Returns a hash code value for this type. |
||||
* |
||||
* @return a hash code value for this type. |
||||
*/ |
||||
@Override |
||||
public int hashCode() { |
||||
int hc = 13 * sort; |
||||
if (sort >= ARRAY) { |
||||
for (int i = off, end = i + len; i < end; i++) { |
||||
hc = 17 * (hc + buf[i]); |
||||
} |
||||
} |
||||
return hc; |
||||
} |
||||
|
||||
/** |
||||
* Returns a string representation of this type. |
||||
* |
||||
* @return the descriptor of this type. |
||||
*/ |
||||
@Override |
||||
public String toString() { |
||||
return getDescriptor(); |
||||
} |
||||
} |
@ -1,196 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.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; |
||||
} |
||||
if (i < n && typePath.charAt(i) == ';') { |
||||
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 followed by ';'. |
||||
*/ |
||||
@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)).append(';'); |
||||
break; |
||||
default: |
||||
result.append('_'); |
||||
} |
||||
} |
||||
return result.toString(); |
||||
} |
||||
} |
@ -1,452 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.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 com.fr.third.org.objectweb.asm.ClassVisitor ClassVisitor}, |
||||
{@link com.fr.third.org.objectweb.asm.FieldVisitor FieldVisitor}, |
||||
{@link com.fr.third.org.objectweb.asm.MethodVisitor MethodVisitor} and |
||||
{@link com.fr.third.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 |
||||
com.fr.third.org.objectweb.asm.ClassReader ClassReader} class, that can parse an |
||||
existing class and make a given visitor visit it. ASM also provides |
||||
a {@link com.fr.third.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 |
||||
com.fr.third.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 |
||||
com.fr.third.org.objectweb.asm.ClassReader ClassReader} class to analyze |
||||
the original class, a class modifier, and a {@link com.fr.third.org.objectweb.asm.ClassWriter |
||||
ClassWriter} to construct the modified class. The class modifier |
||||
is just a {@link com.fr.third.org.objectweb.asm.ClassVisitor ClassVisitor} |
||||
that delegates most of the work to another {@link com.fr.third.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 com.fr.third.org.objectweb.asm.ClassVisitor |
||||
ClassVisitor} and {@link com.fr.third.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> |
@ -1,228 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm.signature; |
||||
|
||||
/** |
||||
* A type signature parser to make a signature visitor visit an existing |
||||
* signature. |
||||
* |
||||
* @author Thomas Hallgren |
||||
* @author Eric Bruneton |
||||
*/ |
||||
public class SignatureReader { |
||||
|
||||
/** |
||||
* The signature to be read. |
||||
*/ |
||||
private final String signature; |
||||
|
||||
/** |
||||
* Constructs a {@link SignatureReader} for the given signature. |
||||
* |
||||
* @param signature |
||||
* A <i>ClassSignature</i>, <i>MethodTypeSignature</i>, or |
||||
* <i>FieldTypeSignature</i>. |
||||
*/ |
||||
public SignatureReader(final String signature) { |
||||
this.signature = signature; |
||||
} |
||||
|
||||
/** |
||||
* Makes the given visitor visit the signature of this |
||||
* {@link SignatureReader}. This signature is the one specified in the |
||||
* constructor (see {@link #SignatureReader(String) SignatureReader}). This |
||||
* method is intended to be called on a {@link SignatureReader} that was |
||||
* created using a <i>ClassSignature</i> (such as the <code>signature</code> |
||||
* parameter of the {@link com.fr.third.org.objectweb.asm.ClassVisitor#visit |
||||
* ClassVisitor.visit} method) or a <i>MethodTypeSignature</i> (such as the |
||||
* <code>signature</code> parameter of the |
||||
* {@link com.fr.third.org.objectweb.asm.ClassVisitor#visitMethod |
||||
* ClassVisitor.visitMethod} method). |
||||
* |
||||
* @param v |
||||
* the visitor that must visit this signature. |
||||
*/ |
||||
public void accept(final SignatureVisitor v) { |
||||
String signature = this.signature; |
||||
int len = signature.length(); |
||||
int pos; |
||||
char c; |
||||
|
||||
if (signature.charAt(0) == '<') { |
||||
pos = 2; |
||||
do { |
||||
int end = signature.indexOf(':', pos); |
||||
v.visitFormalTypeParameter(signature.substring(pos - 1, end)); |
||||
pos = end + 1; |
||||
|
||||
c = signature.charAt(pos); |
||||
if (c == 'L' || c == '[' || c == 'T') { |
||||
pos = parseType(signature, pos, v.visitClassBound()); |
||||
} |
||||
|
||||
while ((c = signature.charAt(pos++)) == ':') { |
||||
pos = parseType(signature, pos, v.visitInterfaceBound()); |
||||
} |
||||
} while (c != '>'); |
||||
} else { |
||||
pos = 0; |
||||
} |
||||
|
||||
if (signature.charAt(pos) == '(') { |
||||
pos++; |
||||
while (signature.charAt(pos) != ')') { |
||||
pos = parseType(signature, pos, v.visitParameterType()); |
||||
} |
||||
pos = parseType(signature, pos + 1, v.visitReturnType()); |
||||
while (pos < len) { |
||||
pos = parseType(signature, pos + 1, v.visitExceptionType()); |
||||
} |
||||
} else { |
||||
pos = parseType(signature, pos, v.visitSuperclass()); |
||||
while (pos < len) { |
||||
pos = parseType(signature, pos, v.visitInterface()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Makes the given visitor visit the signature of this |
||||
* {@link SignatureReader}. This signature is the one specified in the |
||||
* constructor (see {@link #SignatureReader(String) SignatureReader}). This |
||||
* method is intended to be called on a {@link SignatureReader} that was |
||||
* created using a <i>FieldTypeSignature</i>, such as the |
||||
* <code>signature</code> parameter of the |
||||
* {@link com.fr.third.org.objectweb.asm.ClassVisitor#visitField ClassVisitor.visitField} |
||||
* or {@link com.fr.third.org.objectweb.asm.MethodVisitor#visitLocalVariable |
||||
* MethodVisitor.visitLocalVariable} methods. |
||||
* |
||||
* @param v |
||||
* the visitor that must visit this signature. |
||||
*/ |
||||
public void acceptType(final SignatureVisitor v) { |
||||
parseType(this.signature, 0, v); |
||||
} |
||||
|
||||
/** |
||||
* Parses a field type signature and makes the given visitor visit it. |
||||
* |
||||
* @param signature |
||||
* a string containing the signature that must be parsed. |
||||
* @param pos |
||||
* index of the first character of the signature to parsed. |
||||
* @param v |
||||
* the visitor that must visit this signature. |
||||
* @return the index of the first character after the parsed signature. |
||||
*/ |
||||
private static int parseType(final String signature, int pos, |
||||
final SignatureVisitor v) { |
||||
char c; |
||||
int start, end; |
||||
boolean visited, inner; |
||||
String name; |
||||
|
||||
switch (c = signature.charAt(pos++)) { |
||||
case 'Z': |
||||
case 'C': |
||||
case 'B': |
||||
case 'S': |
||||
case 'I': |
||||
case 'F': |
||||
case 'J': |
||||
case 'D': |
||||
case 'V': |
||||
v.visitBaseType(c); |
||||
return pos; |
||||
|
||||
case '[': |
||||
return parseType(signature, pos, v.visitArrayType()); |
||||
|
||||
case 'T': |
||||
end = signature.indexOf(';', pos); |
||||
v.visitTypeVariable(signature.substring(pos, end)); |
||||
return end + 1; |
||||
|
||||
default: // case 'L':
|
||||
start = pos; |
||||
visited = false; |
||||
inner = false; |
||||
for (;;) { |
||||
switch (c = signature.charAt(pos++)) { |
||||
case '.': |
||||
case ';': |
||||
if (!visited) { |
||||
name = signature.substring(start, pos - 1); |
||||
if (inner) { |
||||
v.visitInnerClassType(name); |
||||
} else { |
||||
v.visitClassType(name); |
||||
} |
||||
} |
||||
if (c == ';') { |
||||
v.visitEnd(); |
||||
return pos; |
||||
} |
||||
start = pos; |
||||
visited = false; |
||||
inner = true; |
||||
break; |
||||
|
||||
case '<': |
||||
name = signature.substring(start, pos - 1); |
||||
if (inner) { |
||||
v.visitInnerClassType(name); |
||||
} else { |
||||
v.visitClassType(name); |
||||
} |
||||
visited = true; |
||||
top: for (;;) { |
||||
switch (c = signature.charAt(pos)) { |
||||
case '>': |
||||
break top; |
||||
case '*': |
||||
++pos; |
||||
v.visitTypeArgument(); |
||||
break; |
||||
case '+': |
||||
case '-': |
||||
pos = parseType(signature, pos + 1, |
||||
v.visitTypeArgument(c)); |
||||
break; |
||||
default: |
||||
pos = parseType(signature, pos, |
||||
v.visitTypeArgument('=')); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,238 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm.signature; |
||||
|
||||
import com.fr.third.org.objectweb.asm.Opcodes; |
||||
|
||||
/** |
||||
* A visitor to visit a generic signature. The methods of this interface must be |
||||
* called in one of the three following orders (the last one is the only valid |
||||
* order for a {@link SignatureVisitor} that is returned by a method of this |
||||
* interface): |
||||
* <ul> |
||||
* <li><i>ClassSignature</i> = ( <tt>visitFormalTypeParameter</tt> |
||||
* <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* ( |
||||
* <tt>visitSuperclass</tt> <tt>visitInterface</tt>* )</li> |
||||
* <li><i>MethodSignature</i> = ( <tt>visitFormalTypeParameter</tt> |
||||
* <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* ( |
||||
* <tt>visitParameterType</tt>* <tt>visitReturnType</tt> |
||||
* <tt>visitExceptionType</tt>* )</li> |
||||
* <li><i>TypeSignature</i> = <tt>visitBaseType</tt> | |
||||
* <tt>visitTypeVariable</tt> | <tt>visitArrayType</tt> | ( |
||||
* <tt>visitClassType</tt> <tt>visitTypeArgument</tt>* ( |
||||
* <tt>visitInnerClassType</tt> <tt>visitTypeArgument</tt>* )* <tt>visitEnd</tt> |
||||
* ) )</li> |
||||
* </ul> |
||||
* |
||||
* @author Thomas Hallgren |
||||
* @author Eric Bruneton |
||||
*/ |
||||
public abstract class SignatureVisitor { |
||||
|
||||
/** |
||||
* Wildcard for an "extends" type argument. |
||||
*/ |
||||
public final static char EXTENDS = '+'; |
||||
|
||||
/** |
||||
* Wildcard for a "super" type argument. |
||||
*/ |
||||
public final static char SUPER = '-'; |
||||
|
||||
/** |
||||
* Wildcard for a normal type argument. |
||||
*/ |
||||
public final static char INSTANCEOF = '='; |
||||
|
||||
/** |
||||
* The ASM API version implemented by this visitor. The value of this field |
||||
* must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. |
||||
*/ |
||||
protected final int api; |
||||
|
||||
/** |
||||
* Constructs a new {@link SignatureVisitor}. |
||||
* |
||||
* @param api |
||||
* the ASM API version implemented by this visitor. Must be one |
||||
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. |
||||
*/ |
||||
public SignatureVisitor(final int api) { |
||||
if (api < Opcodes.ASM4 || api > Opcodes.ASM6) { |
||||
throw new IllegalArgumentException(); |
||||
} |
||||
this.api = api; |
||||
} |
||||
|
||||
/** |
||||
* Visits a formal type parameter. |
||||
* |
||||
* @param name |
||||
* the name of the formal parameter. |
||||
*/ |
||||
public void visitFormalTypeParameter(String name) { |
||||
} |
||||
|
||||
/** |
||||
* Visits the class bound of the last visited formal type parameter. |
||||
* |
||||
* @return a non null visitor to visit the signature of the class bound. |
||||
*/ |
||||
public SignatureVisitor visitClassBound() { |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Visits an interface bound of the last visited formal type parameter. |
||||
* |
||||
* @return a non null visitor to visit the signature of the interface bound. |
||||
*/ |
||||
public SignatureVisitor visitInterfaceBound() { |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Visits the type of the super class. |
||||
* |
||||
* @return a non null visitor to visit the signature of the super class
|
||||
* type. |
||||
*/ |
||||
public SignatureVisitor visitSuperclass() { |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Visits the type of an interface implemented by the class. |
||||
* |
||||
* @return a non null visitor to visit the signature of the interface type. |
||||
*/ |
||||
public SignatureVisitor visitInterface() { |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Visits the type of a method parameter. |
||||
* |
||||
* @return a non null visitor to visit the signature of the parameter type. |
||||
*/ |
||||
public SignatureVisitor visitParameterType() { |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Visits the return type of the method. |
||||
* |
||||
* @return a non null visitor to visit the signature of the return type. |
||||
*/ |
||||
public SignatureVisitor visitReturnType() { |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Visits the type of a method exception. |
||||
* |
||||
* @return a non null visitor to visit the signature of the exception type. |
||||
*/ |
||||
public SignatureVisitor visitExceptionType() { |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Visits a signature corresponding to a primitive type. |
||||
* |
||||
* @param descriptor |
||||
* the descriptor of the primitive type, or 'V' for <tt>void</tt> |
||||
* . |
||||
*/ |
||||
public void visitBaseType(char descriptor) { |
||||
} |
||||
|
||||
/** |
||||
* Visits a signature corresponding to a type variable. |
||||
* |
||||
* @param name |
||||
* the name of the type variable. |
||||
*/ |
||||
public void visitTypeVariable(String name) { |
||||
} |
||||
|
||||
/** |
||||
* Visits a signature corresponding to an array type. |
||||
* |
||||
* @return a non null visitor to visit the signature of the array element |
||||
* type. |
||||
*/ |
||||
public SignatureVisitor visitArrayType() { |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Starts the visit of a signature corresponding to a class or interface
|
||||
* type. |
||||
* |
||||
* @param name |
||||
* the internal name of the class or interface. |
||||
*/ |
||||
public void visitClassType(String name) { |
||||
} |
||||
|
||||
/** |
||||
* Visits an inner class. |
||||
* |
||||
* @param name |
||||
* the local name of the inner class in its enclosing class. |
||||
*/ |
||||
public void visitInnerClassType(String name) { |
||||
} |
||||
|
||||
/** |
||||
* Visits an unbounded type argument of the last visited class or inner |
||||
* class type. |
||||
*/ |
||||
public void visitTypeArgument() { |
||||
} |
||||
|
||||
/** |
||||
* Visits a type argument of the last visited class or inner class type. |
||||
* |
||||
* @param wildcard |
||||
* '+', '-' or '='. |
||||
* @return a non null visitor to visit the signature of the type argument. |
||||
*/ |
||||
public SignatureVisitor visitTypeArgument(char wildcard) { |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Ends the visit of a signature corresponding to a class or interface type. |
||||
*/ |
||||
public void visitEnd() { |
||||
} |
||||
} |
@ -1,227 +0,0 @@
|
||||
/*** |
||||
* 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 com.fr.third.org.objectweb.asm.signature; |
||||
|
||||
import com.fr.third.org.objectweb.asm.Opcodes; |
||||
|
||||
/** |
||||
* A signature visitor that generates signatures in string format. |
||||
* |
||||
* @author Thomas Hallgren |
||||
* @author Eric Bruneton |
||||
*/ |
||||
public class SignatureWriter extends SignatureVisitor { |
||||
|
||||
/** |
||||
* Builder used to construct the signature. |
||||
*/ |
||||
private final StringBuilder buf = new StringBuilder(); |
||||
|
||||
/** |
||||
* Indicates if the signature contains formal type parameters. |
||||
*/ |
||||
private boolean hasFormals; |
||||
|
||||
/** |
||||
* Indicates if the signature contains method parameter types. |
||||
*/ |
||||
private boolean hasParameters; |
||||
|
||||
/** |
||||
* Stack used to keep track of class types that have arguments. Each element |
||||
* of this stack is a boolean encoded in one bit. The top of the stack is |
||||
* the lowest order bit. Pushing false = *2, pushing true = *2+1, popping = |
||||
* /2. |
||||
*/ |
||||
private int argumentStack; |
||||
|
||||
/** |
||||
* Constructs a new {@link SignatureWriter} object. |
||||
*/ |
||||
public SignatureWriter() { |
||||
super(Opcodes.ASM6); |
||||
} |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Implementation of the SignatureVisitor interface
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@Override |
||||
public void visitFormalTypeParameter(final String name) { |
||||
if (!hasFormals) { |
||||
hasFormals = true; |
||||
buf.append('<'); |
||||
} |
||||
buf.append(name); |
||||
buf.append(':'); |
||||
} |
||||
|
||||
@Override |
||||
public SignatureVisitor visitClassBound() { |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public SignatureVisitor visitInterfaceBound() { |
||||
buf.append(':'); |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public SignatureVisitor visitSuperclass() { |
||||
endFormals(); |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public SignatureVisitor visitInterface() { |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public SignatureVisitor visitParameterType() { |
||||
endFormals(); |
||||
if (!hasParameters) { |
||||
hasParameters = true; |
||||
buf.append('('); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public SignatureVisitor visitReturnType() { |
||||
endFormals(); |
||||
if (!hasParameters) { |
||||
buf.append('('); |
||||
} |
||||
buf.append(')'); |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public SignatureVisitor visitExceptionType() { |
||||
buf.append('^'); |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public void visitBaseType(final char descriptor) { |
||||
buf.append(descriptor); |
||||
} |
||||
|
||||
@Override |
||||
public void visitTypeVariable(final String name) { |
||||
buf.append('T'); |
||||
buf.append(name); |
||||
buf.append(';'); |
||||
} |
||||
|
||||
@Override |
||||
public SignatureVisitor visitArrayType() { |
||||
buf.append('['); |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public void visitClassType(final String name) { |
||||
buf.append('L'); |
||||
buf.append(name); |
||||
argumentStack *= 2; |
||||
} |
||||
|
||||
@Override |
||||
public void visitInnerClassType(final String name) { |
||||
endArguments(); |
||||
buf.append('.'); |
||||
buf.append(name); |
||||
argumentStack *= 2; |
||||
} |
||||
|
||||
@Override |
||||
public void visitTypeArgument() { |
||||
if (argumentStack % 2 == 0) { |
||||
++argumentStack; |
||||
buf.append('<'); |
||||
} |
||||
buf.append('*'); |
||||
} |
||||
|
||||
@Override |
||||
public SignatureVisitor visitTypeArgument(final char wildcard) { |
||||
if (argumentStack % 2 == 0) { |
||||
++argumentStack; |
||||
buf.append('<'); |
||||
} |
||||
if (wildcard != '=') { |
||||
buf.append(wildcard); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public void visitEnd() { |
||||
endArguments(); |
||||
buf.append(';'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the signature that was built by this signature writer. |
||||
* |
||||
* @return the signature that was built by this signature writer. |
||||
*/ |
||||
@Override |
||||
public String toString() { |
||||
return buf.toString(); |
||||
} |
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Utility methods
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* Ends the formal type parameters section of the signature. |
||||
*/ |
||||
private void endFormals() { |
||||
if (hasFormals) { |
||||
hasFormals = false; |
||||
buf.append('>'); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Ends the type arguments of a class or inner class type. |
||||
*/ |
||||
private void endArguments() { |
||||
if (argumentStack % 2 != 0) { |
||||
buf.append('>'); |
||||
} |
||||
argumentStack /= 2; |
||||
} |
||||
} |
@ -1,36 +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 support for type signatures. |
||||
|
||||
@since ASM 2.0 |
||||
</body> |
||||
</html> |
Loading…
Reference in new issue