mdahm 2003/05/23 00:52:22
Modified: src/java/org/apache/bcel/generic FieldGen.java
MethodGen.java ClassGen.java
Log:
equals() and hashCode() may be parameterized with strategy object
Revision Changes Path
1.2 +55 -2 jakarta-bcel/src/java/org/apache/bcel/generic/FieldGen.java
Index: FieldGen.java
===================================================================
RCS file: /home/cvs/jakarta-bcel/src/java/org/apache/bcel/generic/FieldGen.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- FieldGen.java 29 Oct 2001 20:00:12 -0000 1.1
+++ FieldGen.java 23 May 2003 07:52:22 -0000 1.2
@@ -56,6 +56,8 @@
import org.apache.bcel.Constants;
import org.apache.bcel.classfile.*;
+import org.apache.bcel.util.BCELComparator;
+
import java.util.ArrayList;
import java.util.Iterator;
@@ -65,12 +67,27 @@
* course be compatible with to the declared type).
*
* @version $Id$
- * @author <A HREF="mailto:[email protected]">M. Dahm</A>
+ * @author <A HREF="mailto:[email protected]">M. Dahm</A>
* @see Field
*/
public class FieldGen extends FieldGenOrMethodGen {
private Object value = null;
+ private static BCELComparator _cmp = new BCELComparator() {
+ public boolean equals(Object o1, Object o2) {
+ FieldGen THIS = (FieldGen)o1;
+ FieldGen THAT = (FieldGen)o2;
+
+ return THIS.getName().equals(THAT.getName())
+ && THIS.getSignature().equals(THAT.getSignature());
+ }
+
+ public int hashCode(Object o) {
+ FieldGen THIS = (FieldGen)o;
+ return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
+ }
+ };
+
/**
* Declare a field. If it is static (isStatic() == true) and has a
* basic type like int or String it may have an initial value
@@ -307,4 +324,40 @@
fg.setConstantPool(cp);
return fg;
}
+
+ /**
+ * @return Comparison strategy object
+ */
+ public static BCELComparator getComparator() {
+ return _cmp;
+ }
+
+ /**
+ * @param comparator Comparison strategy object
+ */
+ public static void setComparator(BCELComparator comparator) {
+ _cmp = comparator;
+ }
+
+ /**
+ * Return value as defined by given BCELComparator strategy.
+ * By default two FieldGen objects are said to be equal when
+ * their names and signatures are equal.
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ return _cmp.equals(this, obj);
+ }
+
+ /**
+ * Return value as defined by given BCELComparator strategy.
+ * By default return the hashcode of the field's name XOR signature.
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return _cmp.hashCode(this);
+ }
}
+
1.8 +543 -371 jakarta-bcel/src/java/org/apache/bcel/generic/MethodGen.java
Index: MethodGen.java
===================================================================
RCS file: /home/cvs/jakarta-bcel/src/java/org/apache/bcel/generic/MethodGen.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- MethodGen.java 13 Feb 2003 11:18:23 -0000 1.7
+++ MethodGen.java 23 May 2003 07:52:22 -0000 1.8
@@ -56,6 +56,8 @@
import org.apache.bcel.Constants;
import org.apache.bcel.classfile.*;
+import org.apache.bcel.util.BCELComparator;
+
import java.util.*;
/**
@@ -69,25 +71,40 @@
* The resulting method object can be obtained via the `getMethod()' method.
*
* @version $Id$
- * @author <A HREF="mailto:[email protected]">M. Dahm</A>
+ * @author <A HREF="mailto:[email protected]">M. Dahm</A>
* @author <A HREF="http://www.vmeng.com/beard">Patrick C. Beard</A> [setMaxStack()]
* @see InstructionList
* @see Method
*/
public class MethodGen extends FieldGenOrMethodGen {
- private String class_name;
- private Type[] arg_types;
- private String[] arg_names;
- private int max_locals;
- private int max_stack;
+ private String class_name;
+ private Type[] arg_types;
+ private String[] arg_names;
+ private int max_locals;
+ private int max_stack;
private InstructionList il;
- private boolean strip_attributes;
+ private boolean strip_attributes;
+
+ private ArrayList variable_vec = new ArrayList();
+ private ArrayList line_number_vec = new ArrayList();
+ private ArrayList exception_vec = new ArrayList();
+ private ArrayList throws_vec = new ArrayList();
+ private ArrayList code_attrs_vec = new ArrayList();
+
+ private static BCELComparator _cmp = new BCELComparator() {
+ public boolean equals(Object o1, Object o2) {
+ MethodGen THIS = (MethodGen)o1;
+ MethodGen THAT = (MethodGen)o2;
- private ArrayList variable_vec = new ArrayList();
- private ArrayList line_number_vec = new ArrayList();
- private ArrayList exception_vec = new ArrayList();
- private ArrayList throws_vec = new ArrayList();
- private ArrayList code_attrs_vec = new ArrayList();
+ return THIS.getName().equals(THAT.getName())
+ && THIS.getSignature().equals(THAT.getSignature());
+ }
+
+ public int hashCode(Object o) {
+ MethodGen THIS = (MethodGen)o;
+ return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
+ }
+ };
/**
* Declare method. If the method is non-static the constructor
@@ -111,9 +128,15 @@
* abstract or native methods
* @param cp constant pool
*/
- public MethodGen(int access_flags, Type return_type, Type[] arg_types,
- String[] arg_names, String method_name, String class_name,
- InstructionList il, ConstantPoolGen cp) {
+ public MethodGen(
+ int access_flags,
+ Type return_type,
+ Type[] arg_types,
+ String[] arg_names,
+ String method_name,
+ String class_name,
+ InstructionList il,
+ ConstantPoolGen cp) {
setAccessFlags(access_flags);
setType(return_type);
setArgumentTypes(arg_types);
@@ -125,45 +148,49 @@
boolean abstract_ = isAbstract() || isNative();
InstructionHandle start = null;
- InstructionHandle end = null;
+ InstructionHandle end = null;
- if(!abstract_) {
+ if (!abstract_) {
start = il.getStart();
- end = il.getEnd();
+ end = il.getEnd();
/* Add local variables, namely the implicit `this' and the arguments
*/
- if(!isStatic() && (class_name != null)) { // Instance method -> `this' is local var 0
- addLocalVariable("this", new ObjectType(class_name), start, end);
+ if (!isStatic()
+ && (class_name != null)) { // Instance method -> `this' is local var 0
+ addLocalVariable("this", new ObjectType(class_name), start, end);
}
}
- if(arg_types != null) {
+ if (arg_types != null) {
int size = arg_types.length;
- for(int i=0; i < size; i++) {
- if(Type.VOID == arg_types[i]) {
- throw new ClassGenException("'void' is an illegal argument type for a method");
- }
- }
-
- if(arg_names != null) { // Names for variables provided?
- if(size != arg_names.length)
- throw new ClassGenException("Mismatch in argument array lengths: " +
- size + " vs. " + arg_names.length);
+ for (int i = 0; i < size; i++) {
+ if (Type.VOID == arg_types[i]) {
+ throw new ClassGenException("'void' is an illegal argument type for a method");
+ }
+ }
+
+ if (arg_names != null) { // Names for variables provided?
+ if (size != arg_names.length)
+ throw new ClassGenException(
+ "Mismatch in argument array lengths: "
+ + size
+ + " vs. "
+ + arg_names.length);
} else { // Give them dummy names
- arg_names = new String[size];
-
- for(int i=0; i < size; i++)
- arg_names[i] = "arg" + i;
-
- setArgumentNames(arg_names);
- }
-
- if(!abstract_) {
- for(int i=0; i < size; i++) {
- addLocalVariable(arg_names[i], arg_types[i], start, end);
- }
+ arg_names = new String[size];
+
+ for (int i = 0; i < size; i++)
+ arg_names[i] = "arg" + i;
+
+ setArgumentNames(arg_names);
+ }
+
+ if (!abstract_) {
+ for (int i = 0; i < size; i++) {
+ addLocalVariable(arg_names[i], arg_types[i], start, end);
+ }
}
}
}
@@ -176,94 +203,113 @@
* @param cp constant pool
*/
public MethodGen(Method m, String class_name, ConstantPoolGen cp) {
- this(m.getAccessFlags(), Type.getReturnType(m.getSignature()),
- Type.getArgumentTypes(m.getSignature()), null /* may be overridden anyway */,
- m.getName(), class_name,
- ((m.getAccessFlags() & (Constants.ACC_ABSTRACT | Constants.ACC_NATIVE)) == 0)?
- new InstructionList(m.getCode().getCode()) : null,
- cp);
+ this(
+ m.getAccessFlags(),
+ Type.getReturnType(m.getSignature()),
+ Type.getArgumentTypes(m.getSignature()),
+ null /* may be overridden anyway */
+ ,
+m.getName(),
+ class_name,
+ ((m.getAccessFlags() & (Constants.ACC_ABSTRACT | Constants.ACC_NATIVE))
+ == 0)
+ ? new InstructionList(m.getCode().getCode())
+ : null,
+ cp);
Attribute[] attributes = m.getAttributes();
- for(int i=0; i < attributes.length; i++) {
+ for (int i = 0; i < attributes.length; i++) {
Attribute a = attributes[i];
- if(a instanceof Code) {
- Code c = (Code)a;
- setMaxStack(c.getMaxStack());
- setMaxLocals(c.getMaxLocals());
-
- CodeException[] ces = c.getExceptionTable();
-
- if(ces != null) {
- for(int j=0; j < ces.length; j++) {
- CodeException ce = ces[j];
- int type = ce.getCatchType();
- ObjectType c_type = null;
-
- if(type > 0) {
- String cen = m.getConstantPool().getConstantString(type, Constants.CONSTANT_Class);
- c_type = new ObjectType(cen);
- }
-
- int end_pc = ce.getEndPC();
- int length = m.getCode().getCode().length;
-
- InstructionHandle end;
-
- if(length == end_pc) { // May happen, because end_pc is exclusive
- end = il.getEnd();
- } else {
- end = il.findHandle(end_pc);
- end = end.getPrev(); // Make it inclusive
- }
-
- addExceptionHandler(il.findHandle(ce.getStartPC()), end,
- il.findHandle(ce.getHandlerPC()), c_type);
- }
- }
-
- Attribute[] c_attributes = c.getAttributes();
- for(int j=0; j < c_attributes.length; j++) {
- a = c_attributes[j];
-
- if(a instanceof LineNumberTable) {
- LineNumber[] ln = ((LineNumberTable)a).getLineNumberTable();
-
- for(int k=0; k < ln.length; k++) {
- LineNumber l = ln[k];
- addLineNumber(il.findHandle(l.getStartPC()), l.getLineNumber());
- }
- } else if(a instanceof LocalVariableTable) {
- LocalVariable[] lv = ((LocalVariableTable)a).getLocalVariableTable();
-
- removeLocalVariables();
-
- for(int k=0; k < lv.length; k++) {
- LocalVariable l = lv[k];
- InstructionHandle start = il.findHandle(l.getStartPC());
- InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength());
-
- // Repair malformed handles
- if(null == start) {
- start = il.getStart();
- }
-
- if(null == end) {
- end = il.getEnd();
- }
-
- addLocalVariable(l.getName(), Type.getType(l.getSignature()),
- l.getIndex(), start, end);
- }
- } else
- addCodeAttribute(a);
- }
- } else if(a instanceof ExceptionTable) {
- String[] names = ((ExceptionTable)a).getExceptionNames();
- for(int j=0; j < names.length; j++)
- addException(names[j]);
+ if (a instanceof Code) {
+ Code c = (Code)a;
+ setMaxStack(c.getMaxStack());
+ setMaxLocals(c.getMaxLocals());
+
+ CodeException[] ces = c.getExceptionTable();
+
+ if (ces != null) {
+ for (int j = 0; j < ces.length; j++) {
+ CodeException ce = ces[j];
+ int type = ce.getCatchType();
+ ObjectType c_type = null;
+
+ if (type > 0) {
+ String cen =
+ m.getConstantPool().getConstantString(
+ type,
+ Constants.CONSTANT_Class);
+ c_type = new ObjectType(cen);
+ }
+
+ int end_pc = ce.getEndPC();
+ int length = m.getCode().getCode().length;
+
+ InstructionHandle end;
+
+ if (length == end_pc) { // May happen, because end_pc is exclusive
+ end = il.getEnd();
+ } else {
+ end = il.findHandle(end_pc);
+ end = end.getPrev(); // Make it inclusive
+ }
+
+ addExceptionHandler(
+ il.findHandle(ce.getStartPC()),
+ end,
+ il.findHandle(ce.getHandlerPC()),
+ c_type);
+ }
+ }
+
+ Attribute[] c_attributes = c.getAttributes();
+ for (int j = 0; j < c_attributes.length; j++) {
+ a = c_attributes[j];
+
+ if (a instanceof LineNumberTable) {
+ LineNumber[] ln = ((LineNumberTable)a).getLineNumberTable();
+
+ for (int k = 0; k < ln.length; k++) {
+ LineNumber l = ln[k];
+ addLineNumber(il.findHandle(l.getStartPC()), l.getLineNumber());
+ }
+ } else if (a instanceof LocalVariableTable) {
+ LocalVariable[] lv =
+ ((LocalVariableTable)a).getLocalVariableTable();
+
+ removeLocalVariables();
+
+ for (int k = 0; k < lv.length; k++) {
+ LocalVariable l = lv[k];
+ InstructionHandle start = il.findHandle(l.getStartPC());
+ InstructionHandle end =
+ il.findHandle(l.getStartPC() + l.getLength());
+
+ // Repair malformed handles
+ if (null == start) {
+ start = il.getStart();
+ }
+
+ if (null == end) {
+ end = il.getEnd();
+ }
+
+ addLocalVariable(
+ l.getName(),
+ Type.getType(l.getSignature()),
+ l.getIndex(),
+ start,
+ end);
+ }
+ } else
+ addCodeAttribute(a);
+ }
+ } else if (a instanceof ExceptionTable) {
+ String[] names = ((ExceptionTable)a).getExceptionNames();
+ for (int j = 0; j < names.length; j++)
+ addException(names[j]);
} else
- addAttribute(a);
+ addAttribute(a);
}
}
@@ -279,30 +325,33 @@
* @return new local variable object
* @see LocalVariable
*/
- public LocalVariableGen addLocalVariable(String name, Type type, int slot,
- InstructionHandle start,
- InstructionHandle end) {
+ public LocalVariableGen addLocalVariable(
+ String name,
+ Type type,
+ int slot,
+ InstructionHandle start,
+ InstructionHandle end) {
byte t = type.getType();
- if(t != Constants.T_ADDRESS) {
- int add = type.getSize();
-
- if(slot + add > max_locals)
- max_locals = slot + add;
-
+ if (t != Constants.T_ADDRESS) {
+ int add = type.getSize();
+
+ if (slot + add > max_locals)
+ max_locals = slot + add;
+
LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end);
int i;
-
- if((i = variable_vec.indexOf(l)) >= 0) // Overwrite if necessary
- variable_vec.set(i, l);
+
+ if ((i = variable_vec.indexOf(l)) >= 0) // Overwrite if necessary
+ variable_vec.set(i, l);
else
- variable_vec.add(l);
+ variable_vec.add(l);
return l;
} else {
- throw new IllegalArgumentException("Can not use " + type +
- " as type for local variable");
-
+ throw new IllegalArgumentException(
+ "Can not use " + type + " as type for local variable");
+
}
}
@@ -318,9 +367,11 @@
* @return new local variable object
* @see LocalVariable
*/
- public LocalVariableGen addLocalVariable(String name, Type type,
- InstructionHandle start,
- InstructionHandle end) {
+ public LocalVariableGen addLocalVariable(
+ String name,
+ Type type,
+ InstructionHandle start,
+ InstructionHandle end) {
return addLocalVariable(name, type, max_locals, start, end);
}
@@ -329,7 +380,7 @@
* with an explicit index argument.
*/
public void removeLocalVariable(LocalVariableGen l) {
- variable_vec.remove(l);
+ variable_vec.remove(l);
}
/**
@@ -348,17 +399,25 @@
LocalVariableGen h;
do {
- while(vars[i].getIndex() < m) i++;
- while(m < vars[j].getIndex()) j--;
-
- if(i <= j) {
- h=vars[i]; vars[i]=vars[j]; vars[j]=h; // Swap elements
- i++; j--;
+ while (vars[i].getIndex() < m)
+ i++;
+ while (m < vars[j].getIndex())
+ j--;
+
+ if (i <= j) {
+ h = vars[i];
+ vars[i] = vars[j];
+ vars[j] = h; // Swap elements
+ i++;
+ j--;
}
- } while(i <= j);
+ }
+ while (i <= j);
- if(l < j) sort(vars, l, j);
- if(i < r) sort(vars, i, r);
+ if (l < j)
+ sort(vars, l, j);
+ if (i < r)
+ sort(vars, i, r);
}
/*
@@ -368,19 +427,19 @@
* @return array of declared local variables sorted by index
*/
public LocalVariableGen[] getLocalVariables() {
- int size = variable_vec.size();
- LocalVariableGen[] lg = new LocalVariableGen[size];
+ int size = variable_vec.size();
+ LocalVariableGen[] lg = new LocalVariableGen[size];
variable_vec.toArray(lg);
-
- for(int i=0; i < size; i++) {
- if(lg[i].getStart() == null)
- lg[i].setStart(il.getStart());
- if(lg[i].getEnd() == null)
- lg[i].setEnd(il.getEnd());
+ for (int i = 0; i < size; i++) {
+ if (lg[i].getStart() == null)
+ lg[i].setStart(il.getStart());
+
+ if (lg[i].getEnd() == null)
+ lg[i].setEnd(il.getEnd());
}
- if(size > 1)
+ if (size > 1)
sort(lg, 0, size - 1);
return lg;
@@ -390,15 +449,18 @@
* @return `LocalVariableTable' attribute of all the local variables of this method.
*/
public LocalVariableTable getLocalVariableTable(ConstantPoolGen cp) {
- LocalVariableGen[] lg = getLocalVariables();
- int size = lg.length;
- LocalVariable[] lv = new LocalVariable[size];
+ LocalVariableGen[] lg = getLocalVariables();
+ int size = lg.length;
+ LocalVariable[] lv = new LocalVariable[size];
- for(int i=0; i < size; i++)
+ for (int i = 0; i < size; i++)
lv[i] = lg[i].getLocalVariable(cp);
- return new LocalVariableTable(cp.addUtf8("LocalVariableTable"),
- 2 + lv.length * 10, lv, cp.getConstantPool());
+ return new LocalVariableTable(
+ cp.addUtf8("LocalVariableTable"),
+ 2 + lv.length * 10,
+ lv,
+ cp.getConstantPool());
}
/**
@@ -418,7 +480,7 @@
* Remove a line number.
*/
public void removeLineNumber(LineNumberGen l) {
- line_number_vec.remove(l);
+ line_number_vec.remove(l);
}
/**
@@ -441,16 +503,20 @@
* @return `LineNumberTable' attribute of all the local variables of this method.
*/
public LineNumberTable getLineNumberTable(ConstantPoolGen cp) {
- int size = line_number_vec.size();
- LineNumber[] ln = new LineNumber[size];
+ int size = line_number_vec.size();
+ LineNumber[] ln = new LineNumber[size];
try {
- for(int i=0; i < size; i++)
- ln[i] = ((LineNumberGen)line_number_vec.get(i)).getLineNumber();
- } catch(ArrayIndexOutOfBoundsException e) {} // Never occurs
-
- return new LineNumberTable(cp.addUtf8("LineNumberTable"),
- 2 + ln.length * 4, ln, cp.getConstantPool());
+ for (int i = 0; i < size; i++)
+ ln[i] = ((LineNumberGen)line_number_vec.get(i)).getLineNumber();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ } // Never occurs
+
+ return new LineNumberTable(
+ cp.addUtf8("LineNumberTable"),
+ 2 + ln.length * 4,
+ ln,
+ cp.getConstantPool());
}
/**
@@ -464,15 +530,16 @@
* exception is handled
* @return new exception handler object
*/
- public CodeExceptionGen addExceptionHandler(InstructionHandle start_pc,
- InstructionHandle end_pc,
- InstructionHandle handler_pc,
- ObjectType catch_type) {
- if((start_pc == null) || (end_pc == null) || (handler_pc == null))
+ public CodeExceptionGen addExceptionHandler(
+ InstructionHandle start_pc,
+ InstructionHandle end_pc,
+ InstructionHandle handler_pc,
+ ObjectType catch_type) {
+ if ((start_pc == null) || (end_pc == null) || (handler_pc == null))
throw new ClassGenException("Exception handler target is null instruction");
-
- CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc,
- handler_pc, catch_type);
+
+ CodeExceptionGen c =
+ new CodeExceptionGen(start_pc, end_pc, handler_pc, catch_type);
exception_vec.add(c);
return c;
}
@@ -481,7 +548,7 @@
* Remove an exception handler.
*/
public void removeExceptionHandler(CodeExceptionGen c) {
- exception_vec.remove(c);
+ exception_vec.remove(c);
}
/**
@@ -495,7 +562,7 @@
* @return array of declared exception handlers
*/
public CodeExceptionGen[] getExceptionHandlers() {
- CodeExceptionGen[] cg = new CodeExceptionGen[exception_vec.size()];
+ CodeExceptionGen[] cg = new CodeExceptionGen[exception_vec.size()];
exception_vec.toArray(cg);
return cg;
}
@@ -504,16 +571,17 @@
* @return code exceptions for `Code' attribute
*/
private CodeException[] getCodeExceptions() {
- int size = exception_vec.size();
+ int size = exception_vec.size();
CodeException[] c_exc = new CodeException[size];
try {
- for(int i=0; i < size; i++) {
- CodeExceptionGen c = (CodeExceptionGen)exception_vec.get(i);
- c_exc[i] = c.getCodeException(cp);
+ for (int i = 0; i < size; i++) {
+ CodeExceptionGen c = (CodeExceptionGen)exception_vec.get(i);
+ c_exc[i] = c.getCodeException(cp);
}
- } catch(ArrayIndexOutOfBoundsException e) {}
-
+ } catch (ArrayIndexOutOfBoundsException e) {
+ }
+
return c_exc;
}
@@ -530,14 +598,14 @@
* Remove an exception.
*/
public void removeException(String c) {
- throws_vec.remove(c);
+ throws_vec.remove(c);
}
/**
* Remove all exceptions.
*/
public void removeExceptions() {
- throws_vec.clear();
+ throws_vec.clear();
}
/*
@@ -553,16 +621,20 @@
* @return `Exceptions' attribute of all the exceptions thrown by this method.
*/
private ExceptionTable getExceptionTable(ConstantPoolGen cp) {
- int size = throws_vec.size();
- int[] ex = new int[size];
-
+ int size = throws_vec.size();
+ int[] ex = new int[size];
+
try {
- for(int i=0; i < size; i++)
- ex[i] = cp.addClass((String)throws_vec.get(i));
- } catch(ArrayIndexOutOfBoundsException e) {}
-
- return new ExceptionTable(cp.addUtf8("Exceptions"),
- 2 + 2 * size, ex, cp.getConstantPool());
+ for (int i = 0; i < size; i++)
+ ex[i] = cp.addClass((String)throws_vec.get(i));
+ } catch (ArrayIndexOutOfBoundsException e) {
+ }
+
+ return new ExceptionTable(
+ cp.addUtf8("Exceptions"),
+ 2 + 2 * size,
+ ex,
+ cp.getConstantPool());
}
/**
@@ -574,13 +646,17 @@
*
* @param a attribute to be added
*/
- public void addCodeAttribute(Attribute a) { code_attrs_vec.add(a); }
+ public void addCodeAttribute(Attribute a) {
+ code_attrs_vec.add(a);
+ }
/**
* Remove a code attribute.
*/
- public void removeCodeAttribute(Attribute a) { code_attrs_vec.remove(a); }
-
+ public void removeCodeAttribute(Attribute a) {
+ code_attrs_vec.remove(a);
+ }
+
/**
* Remove all code attributes.
*/
@@ -604,76 +680,85 @@
* @return method object
*/
public Method getMethod() {
- String signature = getSignature();
- int name_index = cp.addUtf8(name);
- int signature_index = cp.addUtf8(signature);
+ String signature = getSignature();
+ int name_index = cp.addUtf8(name);
+ int signature_index = cp.addUtf8(signature);
/* Also updates positions of instructions, i.e., their indices
*/
byte[] byte_code = null;
- if(il != null)
+ if (il != null)
byte_code = il.getByteCode();
- LineNumberTable lnt = null;
+ LineNumberTable lnt = null;
LocalVariableTable lvt = null;
/* Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.)
*/
- if((variable_vec.size() > 0) && !strip_attributes)
+ if ((variable_vec.size() > 0) && !strip_attributes)
addCodeAttribute(lvt = getLocalVariableTable(cp));
- if((line_number_vec.size() > 0) && !strip_attributes)
+ if ((line_number_vec.size() > 0) && !strip_attributes)
addCodeAttribute(lnt = getLineNumberTable(cp));
Attribute[] code_attrs = getCodeAttributes();
/* Each attribute causes 6 additional header bytes
*/
- int attrs_len = 0;
- for(int i=0; i < code_attrs.length; i++)
+ int attrs_len = 0;
+ for (int i = 0; i < code_attrs.length; i++)
attrs_len += (code_attrs[i].getLength() + 6);
- CodeException[] c_exc = getCodeExceptions();
- int exc_len = c_exc.length * 8; // Every entry takes 8 bytes
+ CodeException[] c_exc = getCodeExceptions();
+ int exc_len = c_exc.length * 8; // Every entry takes 8 bytes
Code code = null;
- if((il != null) && !isAbstract()) {
+ if ((il != null) && !isAbstract()) {
// Remove any stale code attribute
Attribute[] attributes = getAttributes();
- for(int i=0; i < attributes.length; i++) {
- Attribute a = attributes[i];
+ for (int i = 0; i < attributes.length; i++) {
+ Attribute a = attributes[i];
- if(a instanceof Code)
- removeAttribute(a);
+ if (a instanceof Code)
+ removeAttribute(a);
}
- code = new Code(cp.addUtf8("Code"),
- 8 + byte_code.length + // prologue byte code
- 2 + exc_len + // exceptions
- 2 + attrs_len, // attributes
- max_stack, max_locals,
- byte_code, c_exc,
- code_attrs,
- cp.getConstantPool());
-
+ code =
+ new Code(
+ cp.addUtf8("Code"),
+ 8 + byte_code.length + // prologue byte code
+ 2 + exc_len + // exceptions
+ 2 + attrs_len, // attributes
+ max_stack, max_locals, byte_code, c_exc, code_attrs, cp.getConstantPool());
+
addAttribute(code);
}
ExceptionTable et = null;
-
- if(throws_vec.size() > 0)
- addAttribute(et = getExceptionTable(cp)); // Add `Exceptions' if there are "throws" clauses
- Method m = new Method(access_flags, name_index, signature_index,
- getAttributes(), cp.getConstantPool());
+ if (throws_vec.size() > 0)
+ addAttribute(et = getExceptionTable(cp));
+ // Add `Exceptions' if there are "throws" clauses
+
+ Method m =
+ new Method(
+ access_flags,
+ name_index,
+ signature_index,
+ getAttributes(),
+ cp.getConstantPool());
// Undo effects of adding attributes
- if(lvt != null) removeCodeAttribute(lvt);
- if(lnt != null) removeCodeAttribute(lnt);
- if(code != null) removeAttribute(code);
- if(et != null) removeAttribute(et);
+ if (lvt != null)
+ removeCodeAttribute(lvt);
+ if (lnt != null)
+ removeCodeAttribute(lnt);
+ if (code != null)
+ removeAttribute(code);
+ if (et != null)
+ removeAttribute(et);
return m;
}
@@ -684,27 +769,27 @@
* exception handlers.
*/
public void removeNOPs() {
- if(il != null) {
+ if (il != null) {
InstructionHandle next;
/* Check branch instructions.
*/
- for(InstructionHandle ih = il.getStart(); ih != null; ih = next) {
- next = ih.next;
+ for (InstructionHandle ih = il.getStart(); ih != null; ih = next) {
+ next = ih.next;
- if((next != null) && (ih.getInstruction() instanceof NOP)) {
- try {
- il.delete(ih);
- } catch(TargetLostException e) {
- InstructionHandle[] targets = e.getTargets();
-
- for(int i=0; i < targets.length; i++) {
- InstructionTargeter[] targeters = targets[i].getTargeters();
-
- for(int j=0; j < targeters.length; j++)
- targeters[j].updateTarget(targets[i], next);
- }
- }
- }
+ if ((next != null) && (ih.getInstruction() instanceof NOP)) {
+ try {
+ il.delete(ih);
+ } catch (TargetLostException e) {
+ InstructionHandle[] targets = e.getTargets();
+
+ for (int i = 0; i < targets.length; i++) {
+ InstructionTargeter[] targeters = targets[i].getTargeters();
+
+ for (int j = 0; j < targeters.length; j++)
+ targeters[j].updateTarget(targets[i], next);
+ }
+ }
+ }
}
}
}
@@ -712,37 +797,73 @@
/**
* Set maximum number of local variables.
*/
- public void setMaxLocals(int m) { max_locals = m; }
- public int getMaxLocals() { return max_locals; }
+ public void setMaxLocals(int m) {
+ max_locals = m;
+ }
+ public int getMaxLocals() {
+ return max_locals;
+ }
/**
* Set maximum stack size for this method.
*/
- public void setMaxStack(int m) { max_stack = m; }
- public int getMaxStack() { return max_stack; }
+ public void setMaxStack(int m) {
+ max_stack = m;
+ }
+ public int getMaxStack() {
+ return max_stack;
+ }
/** @return class that contains this method
*/
- public String getClassName() { return class_name; }
- public void setClassName(String class_name) { this.class_name = class_name; }
+ public String getClassName() {
+ return class_name;
+ }
+ public void setClassName(String class_name) {
+ this.class_name = class_name;
+ }
- public void setReturnType(Type return_type) { setType(return_type); }
- public Type getReturnType() { return getType(); }
+ public void setReturnType(Type return_type) {
+ setType(return_type);
+ }
+ public Type getReturnType() {
+ return getType();
+ }
- public void setArgumentTypes(Type[] arg_types) { this.arg_types = arg_types; }
- public Type[] getArgumentTypes() { return (Type[])arg_types.clone(); }
- public void setArgumentType(int i, Type type) { arg_types[i] = type; }
- public Type getArgumentType(int i) { return arg_types[i]; }
-
- public void setArgumentNames(String[] arg_names) { this.arg_names = arg_names; }
- public String[] getArgumentNames() { return (String[])arg_names.clone(); }
- public void setArgumentName(int i, String name) { arg_names[i] = name; }
- public String getArgumentName(int i) { return arg_names[i]; }
+ public void setArgumentTypes(Type[] arg_types) {
+ this.arg_types = arg_types;
+ }
+ public Type[] getArgumentTypes() {
+ return (Type[])arg_types.clone();
+ }
+ public void setArgumentType(int i, Type type) {
+ arg_types[i] = type;
+ }
+ public Type getArgumentType(int i) {
+ return arg_types[i];
+ }
+
+ public void setArgumentNames(String[] arg_names) {
+ this.arg_names = arg_names;
+ }
+ public String[] getArgumentNames() {
+ return (String[])arg_names.clone();
+ }
+ public void setArgumentName(int i, String name) {
+ arg_names[i] = name;
+ }
+ public String getArgumentName(int i) {
+ return arg_names[i];
+ }
- public InstructionList getInstructionList() { return il; }
- public void setInstructionList(InstructionList il) { this.il = il; }
+ public InstructionList getInstructionList() {
+ return il;
+ }
+ public void setInstructionList(InstructionList il) {
+ this.il = il;
+ }
- public String getSignature() {
+ public String getSignature() {
return Type.getMethodSignature(type, arg_types);
}
@@ -750,7 +871,7 @@
* Computes max. stack size by performing control flow analysis.
*/
public void setMaxStack() {
- if(il != null)
+ if (il != null)
max_stack = getMaxStack(cp, il, getExceptionHandlers());
else
max_stack = 0;
@@ -760,25 +881,28 @@
* Compute maximum number of local variables.
*/
public void setMaxLocals() {
- if(il != null) {
- int max = isStatic()? 0 : 1;
+ if (il != null) {
+ int max = isStatic() ? 0 : 1;
- if(arg_types != null)
- for(int i=0; i < arg_types.length; i++)
- max += arg_types[i].getSize();
-
- for(InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) {
- Instruction ins = ih.getInstruction();
-
- if((ins instanceof LocalVariableInstruction) ||
- (ins instanceof RET) || (ins instanceof IINC))
- {
- int index = ((IndexedInstruction)ins).getIndex() +
- ((TypedInstruction)ins).getType(cp).getSize();
-
- if(index > max)
- max = index;
- }
+ if (arg_types != null)
+ for (int i = 0; i < arg_types.length; i++)
+ max += arg_types[i].getSize();
+
+ for (InstructionHandle ih = il.getStart();
+ ih != null;
+ ih = ih.getNext()) {
+ Instruction ins = ih.getInstruction();
+
+ if ((ins instanceof LocalVariableInstruction)
+ || (ins instanceof RET)
+ || (ins instanceof IINC)) {
+ int index =
+ ((IndexedInstruction)ins).getIndex()
+ + ((TypedInstruction)ins).getType(cp).getSize();
+
+ if (index > max)
+ max = index;
+ }
}
max_locals = max;
@@ -789,45 +913,49 @@
/** Do not/Do produce attributes code attributesLineNumberTable and
* LocalVariableTable, like javac -O
*/
- public void stripAttributes(boolean flag) { strip_attributes = flag; }
+ public void stripAttributes(boolean flag) {
+ strip_attributes = flag;
+ }
static final class BranchTarget {
InstructionHandle target;
- int stackDepth;
-
+ int stackDepth;
+
BranchTarget(InstructionHandle target, int stackDepth) {
this.target = target;
this.stackDepth = stackDepth;
}
}
-
+
static final class BranchStack {
- Stack branchTargets = new Stack();
+ Stack branchTargets = new Stack();
Hashtable visitedTargets = new Hashtable();
public void push(InstructionHandle target, int stackDepth) {
- if(visited(target))
- return;
+ if (visited(target))
+ return;
branchTargets.push(visit(target, stackDepth));
}
-
+
public BranchTarget pop() {
- if(!branchTargets.empty()) {
- BranchTarget bt = (BranchTarget) branchTargets.pop();
- return bt;
+ if (!branchTargets.empty()) {
+ BranchTarget bt = (BranchTarget)branchTargets.pop();
+ return bt;
}
return null;
}
-
- private final BranchTarget visit(InstructionHandle target, int stackDepth) {
+
+ private final BranchTarget visit(
+ InstructionHandle target,
+ int stackDepth) {
BranchTarget bt = new BranchTarget(target, stackDepth);
visitedTargets.put(target, bt);
return bt;
}
-
+
private final boolean visited(InstructionHandle target) {
return (visitedTargets.get(target) != null);
}
@@ -838,9 +966,12 @@
*
* @return maximum stack depth used by method
*/
- public static int getMaxStack(ConstantPoolGen cp, InstructionList il, CodeExceptionGen[] et) {
+ public static int getMaxStack(
+ ConstantPoolGen cp,
+ InstructionList il,
+ CodeExceptionGen[] et) {
BranchStack branchTargets = new BranchStack();
-
+
/* Initially, populate the branch stack with the exception
* handlers, because these aren't (necessarily) branched to
* explicitly. in each case, the stack will have depth 1,
@@ -849,59 +980,60 @@
for (int i = 0; i < et.length; i++) {
InstructionHandle handler_pc = et[i].getHandlerPC();
if (handler_pc != null)
- branchTargets.push(handler_pc, 1);
+ branchTargets.push(handler_pc, 1);
}
-
- int stackDepth = 0, maxStackDepth = 0;
- InstructionHandle ih = il.getStart();
- while(ih != null) {
+ int stackDepth = 0, maxStackDepth = 0;
+ InstructionHandle ih = il.getStart();
+
+ while (ih != null) {
Instruction instruction = ih.getInstruction();
short opcode = instruction.getOpcode();
int delta = instruction.produceStack(cp) - instruction.consumeStack(cp);
stackDepth += delta;
- if(stackDepth > maxStackDepth)
- maxStackDepth = stackDepth;
+ if (stackDepth > maxStackDepth)
+ maxStackDepth = stackDepth;
// choose the next instruction based on whether current is a branch.
- if(instruction instanceof BranchInstruction) {
- BranchInstruction branch = (BranchInstruction) instruction;
- if(instruction instanceof Select) {
- // explore all of the select's targets. the default target is handled below.
- Select select = (Select) branch;
- InstructionHandle[] targets = select.getTargets();
- for (int i = 0; i < targets.length; i++)
- branchTargets.push(targets[i], stackDepth);
- // nothing to fall through to.
- ih = null;
- } else if(!(branch instanceof IfInstruction)) {
- // if an instruction that comes back to following PC,
- // push next instruction, with stack depth reduced by 1.
- if(opcode == Constants.JSR || opcode == Constants.JSR_W)
- branchTargets.push(ih.getNext(), stackDepth - 1);
- ih = null;
- }
- // for all branches, the target of the branch is pushed on the branch stack.
- // conditional branches have a fall through case, selects don't, and
- // jsr/jsr_w return to the next instruction.
- branchTargets.push(branch.getTarget(), stackDepth);
+ if (instruction instanceof BranchInstruction) {
+ BranchInstruction branch = (BranchInstruction)instruction;
+ if (instruction instanceof Select) {
+ // explore all of the select's targets. the default target is handled below.
+ Select select = (Select)branch;
+ InstructionHandle[] targets = select.getTargets();
+ for (int i = 0; i < targets.length; i++)
+ branchTargets.push(targets[i], stackDepth);
+ // nothing to fall through to.
+ ih = null;
+ } else if (!(branch instanceof IfInstruction)) {
+ // if an instruction that comes back to following PC,
+ // push next instruction, with stack depth reduced by 1.
+ if (opcode == Constants.JSR || opcode == Constants.JSR_W)
+ branchTargets.push(ih.getNext(), stackDepth - 1);
+ ih = null;
+ }
+ // for all branches, the target of the branch is pushed on the branch stack.
+ // conditional branches have a fall through case, selects don't, and
+ // jsr/jsr_w return to the next instruction.
+ branchTargets.push(branch.getTarget(), stackDepth);
} else {
- // check for instructions that terminate the method.
- if(opcode == Constants.ATHROW || opcode == Constants.RET ||
- (opcode >= Constants.IRETURN && opcode <= Constants.RETURN))
- ih = null;
+ // check for instructions that terminate the method.
+ if (opcode == Constants.ATHROW
+ || opcode == Constants.RET
+ || (opcode >= Constants.IRETURN && opcode <= Constants.RETURN))
+ ih = null;
}
// normal case, go to the next instruction.
- if(ih != null)
- ih = ih.getNext();
+ if (ih != null)
+ ih = ih.getNext();
// if we have no more instructions, see if there are any deferred branches to explore.
- if(ih == null) {
- BranchTarget bt = branchTargets.pop();
- if (bt != null) {
- ih = bt.target;
- stackDepth = bt.stackDepth;
- }
+ if (ih == null) {
+ BranchTarget bt = branchTargets.pop();
+ if (bt != null) {
+ ih = bt.target;
+ stackDepth = bt.stackDepth;
+ }
}
}
@@ -913,7 +1045,7 @@
/** Add observer for this object.
*/
public void addObserver(MethodObserver o) {
- if(observers == null)
+ if (observers == null)
observers = new ArrayList();
observers.add(o);
@@ -922,7 +1054,7 @@
/** Remove observer for this object.
*/
public void removeObserver(MethodObserver o) {
- if(observers != null)
+ if (observers != null)
observers.remove(o);
}
@@ -931,9 +1063,9 @@
* called by the user after he has finished editing the object.
*/
public void update() {
- if(observers != null)
- for(Iterator e = observers.iterator(); e.hasNext(); )
- ((MethodObserver)e.next()).notify(this);
+ if (observers != null)
+ for (Iterator e = observers.iterator(); e.hasNext();)
+ ((MethodObserver)e.next()).notify(this);
}
/**
@@ -943,33 +1075,73 @@
* @return String representation of the method.
*/
public final String toString() {
- String access = Utility.accessToString(access_flags);
+ String access = Utility.accessToString(access_flags);
String signature = Type.getMethodSignature(type, arg_types);
- signature = Utility.methodSignatureToString(signature, name, access,
- true, getLocalVariableTable(cp));
+ signature =
+ Utility.methodSignatureToString(
+ signature,
+ name,
+ access,
+ true,
+ getLocalVariableTable(cp));
StringBuffer buf = new StringBuffer(signature);
- if(throws_vec.size() > 0) {
- for(Iterator e = throws_vec.iterator(); e.hasNext(); )
- buf.append("\n\t\tthrows " + e.next());
+ if (throws_vec.size() > 0) {
+ for (Iterator e = throws_vec.iterator(); e.hasNext();)
+ buf.append("\n\t\tthrows " + e.next());
}
-
+
return buf.toString();
}
/** @return deep copy of this method
*/
public MethodGen copy(String class_name, ConstantPoolGen cp) {
- Method m = ((MethodGen)clone()).getMethod();
+ Method m = ((MethodGen)clone()).getMethod();
MethodGen mg = new MethodGen(m, class_name, this.cp);
- if(this.cp != cp) {
+ if (this.cp != cp) {
mg.setConstantPool(cp);
mg.getInstructionList().replaceConstantPool(this.cp, cp);
}
return mg;
- }
+ }
+
+ /**
+ * @return Comparison strategy object
+ */
+ public static BCELComparator getComparator() {
+ return _cmp;
+ }
+
+ /**
+ * @param comparator Comparison strategy object
+ */
+ public static void setComparator(BCELComparator comparator) {
+ _cmp = comparator;
+ }
+
+ /**
+ * Return value as defined by given BCELComparator strategy.
+ * By default two MethodGen objects are said to be equal when
+ * their names and signatures are equal.
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ return _cmp.equals(this, obj);
+ }
+
+ /**
+ * Return value as defined by given BCELComparator strategy.
+ * By default return the hashcode of the method's name XOR signature.
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return _cmp.hashCode(this);
+ }
}
1.4 +222 -98 jakarta-bcel/src/java/org/apache/bcel/generic/ClassGen.java
Index: ClassGen.java
===================================================================
RCS file: /home/cvs/jakarta-bcel/src/java/org/apache/bcel/generic/ClassGen.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ClassGen.java 4 Mar 2002 13:36:57 -0000 1.3
+++ ClassGen.java 23 May 2003 07:52:22 -0000 1.4
@@ -56,6 +56,8 @@
import org.apache.bcel.Constants;
import org.apache.bcel.classfile.*;
+import org.apache.bcel.util.BCELComparator;
+
import java.util.ArrayList;
import java.util.Iterator;
@@ -65,22 +67,36 @@
*
* @see JavaClass
* @version $Id$
- * @author <A HREF="mailto:[email protected]">M. Dahm</A>
+ * @author <A HREF="mailto:[email protected]">M. Dahm</A>
*/
public class ClassGen extends AccessFlags implements Cloneable {
/* Corresponds to the fields found in a JavaClass object.
*/
- private String class_name, super_class_name, file_name;
- private int class_name_index = -1, superclass_name_index = -1;
- private int major = Constants.MAJOR_1_1, minor = Constants.MINOR_1_1;
+ private String class_name, super_class_name, file_name;
+ private int class_name_index = -1, superclass_name_index = -1;
+ private int major = Constants.MAJOR_1_1, minor = Constants.MINOR_1_1;
private ConstantPoolGen cp; // Template for building up constant pool
// ArrayLists instead of arrays to gather fields, methods, etc.
- private ArrayList field_vec = new ArrayList();
- private ArrayList method_vec = new ArrayList();
- private ArrayList attribute_vec = new ArrayList();
- private ArrayList interface_vec = new ArrayList();
+ private ArrayList field_vec = new ArrayList();
+ private ArrayList method_vec = new ArrayList();
+ private ArrayList attribute_vec = new ArrayList();
+ private ArrayList interface_vec = new ArrayList();
+
+ private static BCELComparator _cmp = new BCELComparator() {
+ public boolean equals(Object o1, Object o2) {
+ ClassGen THIS = (ClassGen)o1;
+ ClassGen THAT = (ClassGen)o2;
+
+ return THIS.getClassName().equals(THAT.getClassName());
+ }
+
+ public int hashCode(Object o) {
+ ClassGen THIS = (ClassGen)o;
+ return THIS.getClassName().hashCode();
+ }
+ };
/** Convenience constructor to set up some important values initially.
*
@@ -91,25 +107,34 @@
* @param interfaces implemented interfaces
* @param cp constant pool to use
*/
- public ClassGen(String class_name, String super_class_name, String file_name,
- int access_flags, String[] interfaces, ConstantPoolGen cp) {
- this.class_name = class_name;
+ public ClassGen(
+ String class_name,
+ String super_class_name,
+ String file_name,
+ int access_flags,
+ String[] interfaces,
+ ConstantPoolGen cp) {
+ this.class_name = class_name;
this.super_class_name = super_class_name;
- this.file_name = file_name;
- this.access_flags = access_flags;
- this.cp = cp;
+ this.file_name = file_name;
+ this.access_flags = access_flags;
+ this.cp = cp;
// Put everything needed by default into the constant pool and the vectors
- if(file_name != null)
- addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2,
- cp.addUtf8(file_name), cp.getConstantPool()));
+ if (file_name != null)
+ addAttribute(
+ new SourceFile(
+ cp.addUtf8("SourceFile"),
+ 2,
+ cp.addUtf8(file_name),
+ cp.getConstantPool()));
- class_name_index = cp.addClass(class_name);
+ class_name_index = cp.addClass(class_name);
superclass_name_index = cp.addClass(super_class_name);
- if(interfaces != null)
- for(int i=0; i < interfaces.length; i++)
- addInterface(interfaces[i]);
+ if (interfaces != null)
+ for (int i = 0; i < interfaces.length; i++)
+ addInterface(interfaces[i]);
}
/** Convenience constructor to set up some important values initially.
@@ -120,10 +145,19 @@
* @param access_flags access qualifiers
* @param interfaces implemented interfaces
*/
- public ClassGen(String class_name, String super_class_name, String file_name,
- int access_flags, String[] interfaces) {
- this(class_name, super_class_name, file_name, access_flags, interfaces,
- new ConstantPoolGen());
+ public ClassGen(
+ String class_name,
+ String super_class_name,
+ String file_name,
+ int access_flags,
+ String[] interfaces) {
+ this(
+ class_name,
+ super_class_name,
+ file_name,
+ access_flags,
+ interfaces,
+ new ConstantPoolGen());
}
/**
@@ -131,31 +165,31 @@
* @param clazz JavaClass object (e.g. read from file)
*/
public ClassGen(JavaClass clazz) {
- class_name_index = clazz.getClassNameIndex();
+ class_name_index = clazz.getClassNameIndex();
superclass_name_index = clazz.getSuperclassNameIndex();
- class_name = clazz.getClassName();
- super_class_name = clazz.getSuperclassName();
- file_name = clazz.getSourceFileName();
- access_flags = clazz.getAccessFlags();
- cp = new ConstantPoolGen(clazz.getConstantPool());
- major = clazz.getMajor();
- minor = clazz.getMinor();
+ class_name = clazz.getClassName();
+ super_class_name = clazz.getSuperclassName();
+ file_name = clazz.getSourceFileName();
+ access_flags = clazz.getAccessFlags();
+ cp = new ConstantPoolGen(clazz.getConstantPool());
+ major = clazz.getMajor();
+ minor = clazz.getMinor();
Attribute[] attributes = clazz.getAttributes();
- Method[] methods = clazz.getMethods();
- Field[] fields = clazz.getFields();
- String[] interfaces = clazz.getInterfaceNames();
-
- for(int i=0; i < interfaces.length; i++)
+ Method[] methods = clazz.getMethods();
+ Field[] fields = clazz.getFields();
+ String[] interfaces = clazz.getInterfaceNames();
+
+ for (int i = 0; i < interfaces.length; i++)
addInterface(interfaces[i]);
- for(int i=0; i < attributes.length; i++)
+ for (int i = 0; i < attributes.length; i++)
addAttribute(attributes[i]);
- for(int i=0; i < methods.length; i++)
+ for (int i = 0; i < methods.length; i++)
addMethod(methods[i]);
- for(int i=0; i < fields.length; i++)
+ for (int i = 0; i < fields.length; i++)
addField(fields[i]);
}
@@ -163,17 +197,26 @@
* @return the (finally) built up Java class object.
*/
public JavaClass getJavaClass() {
- int[] interfaces = getInterfaces();
- Field[] fields = getFields();
- Method[] methods = getMethods();
- Attribute[] attributes = getAttributes();
+ int[] interfaces = getInterfaces();
+ Field[] fields = getFields();
+ Method[] methods = getMethods();
+ Attribute[] attributes = getAttributes();
// Must be last since the above calls may still add something to it
- ConstantPool cp = this.cp.getFinalConstantPool();
-
- return new JavaClass(class_name_index, superclass_name_index,
- file_name, major, minor, access_flags,
- cp, interfaces, fields, methods, attributes);
+ ConstantPool cp = this.cp.getFinalConstantPool();
+
+ return new JavaClass(
+ class_name_index,
+ superclass_name_index,
+ file_name,
+ major,
+ minor,
+ access_flags,
+ cp,
+ interfaces,
+ fields,
+ methods,
+ attributes);
}
/**
@@ -195,38 +238,46 @@
/**
* @return major version number of class file
*/
- public int getMajor() { return major; }
+ public int getMajor() {
+ return major;
+ }
/** Set major version number of class file, default value is 45 (JDK 1.1)
* @param major major version number
*/
public void setMajor(int major) {
this.major = major;
- }
+ }
/** Set minor version number of class file, default value is 3 (JDK 1.1)
* @param minor minor version number
*/
public void setMinor(int minor) {
this.minor = minor;
- }
+ }
/**
* @return minor version number of class file
*/
- public int getMinor() { return minor; }
+ public int getMinor() {
+ return minor;
+ }
/**
* Add an attribute to this class.
* @param a attribute to add
*/
- public void addAttribute(Attribute a) { attribute_vec.add(a); }
+ public void addAttribute(Attribute a) {
+ attribute_vec.add(a);
+ }
/**
* Add a method to this class.
* @param m method to add
*/
- public void addMethod(Method m) { method_vec.add(m); }
+ public void addMethod(Method m) {
+ method_vec.add(m);
+ }
/**
* Convenience method.
@@ -237,12 +288,20 @@
public void addEmptyConstructor(int access_flags) {
InstructionList il = new InstructionList();
il.append(InstructionConstants.THIS); // Push `this'
- il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name,
- "<init>", "()V")));
+ il.append(
+ new INVOKESPECIAL(cp.addMethodref(super_class_name, "<init>", "()V")));
il.append(InstructionConstants.RETURN);
- MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null,
- "<init>", class_name, il, cp);
+ MethodGen mg =
+ new MethodGen(
+ access_flags,
+ Type.VOID,
+ Type.NO_ARGS,
+ null,
+ "<init>",
+ class_name,
+ il,
+ cp);
mg.setMaxStack(1);
addMethod(mg.getMethod());
}
@@ -251,17 +310,21 @@
* Add a field to this class.
* @param f field to add
*/
- public void addField(Field f) { field_vec.add(f); }
+ public void addField(Field f) {
+ field_vec.add(f);
+ }
+
+ public boolean containsField(Field f) {
+ return field_vec.contains(f);
+ }
- public boolean containsField(Field f) { return field_vec.contains(f); }
-
/** @return field object with given name, or null
*/
public Field containsField(String name) {
- for(Iterator e=field_vec.iterator(); e.hasNext(); ) {
+ for (Iterator e = field_vec.iterator(); e.hasNext();) {
Field f = (Field)e.next();
- if(f.getName().equals(name))
- return f;
+ if (f.getName().equals(name))
+ return f;
}
return null;
@@ -270,10 +333,10 @@
/** @return method object with given name and signature, or null
*/
public Method containsMethod(String name, String signature) {
- for(Iterator e=method_vec.iterator(); e.hasNext();) {
+ for (Iterator e = method_vec.iterator(); e.hasNext();) {
Method m = (Method)e.next();
- if(m.getName().equals(name) && m.getSignature().equals(signature))
- return m;
+ if (m.getName().equals(name) && m.getSignature().equals(signature))
+ return m;
}
return null;
@@ -283,24 +346,28 @@
* Remove an attribute from this class.
* @param a attribute to remove
*/
- public void removeAttribute(Attribute a) { attribute_vec.remove(a); }
+ public void removeAttribute(Attribute a) {
+ attribute_vec.remove(a);
+ }
/**
* Remove a method from this class.
* @param m method to remove
*/
- public void removeMethod(Method m) { method_vec.remove(m); }
+ public void removeMethod(Method m) {
+ method_vec.remove(m);
+ }
/** Replace given method with new one. If the old one does not exist
* add the new_ method to the class anyway.
*/
public void replaceMethod(Method old, Method new_) {
- if(new_ == null)
+ if (new_ == null)
throw new ClassGenException("Replacement method must not be null");
int i = method_vec.indexOf(old);
- if(i < 0)
+ if (i < 0)
method_vec.add(new_);
else
method_vec.set(i, new_);
@@ -310,12 +377,12 @@
* add the new_ field to the class anyway.
*/
public void replaceField(Field old, Field new_) {
- if(new_ == null)
+ if (new_ == null)
throw new ClassGenException("Replacement method must not be null");
int i = field_vec.indexOf(old);
- if(i < 0)
+ if (i < 0)
field_vec.add(new_);
else
field_vec.set(i, new_);
@@ -325,11 +392,19 @@
* Remove a field to this class.
* @param f field to remove
*/
- public void removeField(Field f) { field_vec.remove(f); }
+ public void removeField(Field f) {
+ field_vec.remove(f);
+ }
- public String getClassName() { return class_name; }
- public String getSuperclassName() { return super_class_name; }
- public String getFileName() { return file_name; }
+ public String getClassName() {
+ return class_name;
+ }
+ public String getSuperclassName() {
+ return super_class_name;
+ }
+ public String getFileName() {
+ return file_name;
+ }
public void setClassName(String name) {
class_name = name.replace('/', '.');
@@ -349,7 +424,7 @@
public void setMethods(Method[] methods) {
method_vec.clear();
- for(int m=0; m<methods.length; m++)
+ for (int m = 0; m < methods.length; m++)
addMethod(methods[m]);
}
@@ -362,7 +437,7 @@
}
public String[] getInterfaceNames() {
- int size = interface_vec.size();
+ int size = interface_vec.size();
String[] interfaces = new String[size];
interface_vec.toArray(interfaces);
@@ -370,10 +445,10 @@
}
public int[] getInterfaces() {
- int size = interface_vec.size();
+ int size = interface_vec.size();
int[] interfaces = new int[size];
- for(int i=0; i < size; i++)
+ for (int i = 0; i < size; i++)
interfaces[i] = cp.addClass((String)interface_vec.get(i));
return interfaces;
@@ -391,33 +466,45 @@
return attributes;
}
- public ConstantPoolGen getConstantPool() { return cp; }
+ public ConstantPoolGen getConstantPool() {
+ return cp;
+ }
public void setConstantPool(ConstantPoolGen constant_pool) {
cp = constant_pool;
- }
+ }
public void setClassNameIndex(int class_name_index) {
this.class_name_index = class_name_index;
- class_name = cp.getConstantPool().
- getConstantString(class_name_index, Constants.CONSTANT_Class).replace('/', '.');
+ class_name =
+ cp
+ .getConstantPool()
+ .getConstantString(class_name_index, Constants.CONSTANT_Class)
+ .replace('/', '.');
}
public void setSuperclassNameIndex(int superclass_name_index) {
this.superclass_name_index = superclass_name_index;
- super_class_name = cp.getConstantPool().
- getConstantString(superclass_name_index, Constants.CONSTANT_Class).replace('/', '.');
+ super_class_name =
+ cp
+ .getConstantPool()
+ .getConstantString(superclass_name_index, Constants.CONSTANT_Class)
+ .replace('/', '.');
}
- public int getSuperclassNameIndex() { return superclass_name_index; }
+ public int getSuperclassNameIndex() {
+ return superclass_name_index;
+ }
- public int getClassNameIndex() { return class_name_index; }
+ public int getClassNameIndex() {
+ return class_name_index;
+ }
private ArrayList observers;
/** Add observer for this object.
*/
public void addObserver(ClassObserver o) {
- if(observers == null)
+ if (observers == null)
observers = new ArrayList();
observers.add(o);
@@ -426,7 +513,7 @@
/** Remove observer for this object.
*/
public void removeObserver(ClassObserver o) {
- if(observers != null)
+ if (observers != null)
observers.remove(o);
}
@@ -435,17 +522,54 @@
* called by the user after he has finished editing the object.
*/
public void update() {
- if(observers != null)
- for(Iterator e = observers.iterator(); e.hasNext(); )
- ((ClassObserver)e.next()).notify(this);
+ if (observers != null) {
+ for (Iterator e = observers.iterator(); e.hasNext();) {
+ ((ClassObserver)e.next()).notify(this);
+ }
+ }
}
public Object clone() {
try {
return super.clone();
- } catch(CloneNotSupportedException e) {
+ } catch (CloneNotSupportedException e) {
System.err.println(e);
return null;
}
}
+
+ /**
+ * @return Comparison strategy object
+ */
+ public static BCELComparator getComparator() {
+ return _cmp;
+ }
+
+ /**
+ * @param comparator Comparison strategy object
+ */
+ public static void setComparator(BCELComparator comparator) {
+ _cmp = comparator;
+ }
+
+ /**
+ * Return value as defined by given BCELComparator strategy.
+ * By default two ClassGen objects are said to be equal when
+ * their class names are equal.
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ return _cmp.equals(this, obj);
+ }
+
+ /**
+ * Return value as defined by given BCELComparator strategy.
+ * By default return the hashcode of the class name.
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return _cmp.hashCode(this);
+ }
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.