< prev index next >
src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldOrMethod.java
Print this page
@@ -19,66 +19,125 @@
* limitations under the License.
*/
package com.sun.org.apache.bcel.internal.generic;
-import com.sun.org.apache.bcel.internal.classfile.*;
+import com.sun.org.apache.bcel.internal.Const;
+import com.sun.org.apache.bcel.internal.classfile.ConstantCP;
+import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType;
+import com.sun.org.apache.bcel.internal.classfile.ConstantPool;
+import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8;
/**
* Super class for InvokeInstruction and FieldInstruction, since they have
* some methods in common!
*
- * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @version $Id: FieldOrMethod.java 1749603 2016-06-21 20:50:19Z ggregory $
*/
public abstract class FieldOrMethod extends CPInstruction implements LoadClass {
+
/**
* Empty constructor needed for the Class.newInstance() statement in
* Instruction.readInstruction(). Not to be used otherwise.
*/
- FieldOrMethod() {}
+ FieldOrMethod() {
+ }
+
/**
* @param index to constant pool
*/
- protected FieldOrMethod(short opcode, int index) {
+ protected FieldOrMethod(final short opcode, final int index) {
super(opcode, index);
}
+
/** @return signature of referenced method/field.
*/
- public String getSignature(ConstantPoolGen cpg) {
- ConstantPool cp = cpg.getConstantPool();
- ConstantCP cmr = (ConstantCP)cp.getConstant(index);
- ConstantNameAndType cnat = (ConstantNameAndType)cp.getConstant(cmr.getNameAndTypeIndex());
-
- return ((ConstantUtf8)cp.getConstant(cnat.getSignatureIndex())).getBytes();
+ public String getSignature( final ConstantPoolGen cpg ) {
+ final ConstantPool cp = cpg.getConstantPool();
+ final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex());
+ final ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex());
+ return ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getBytes();
}
+
/** @return name of referenced method/field.
*/
- public String getName(ConstantPoolGen cpg) {
- ConstantPool cp = cpg.getConstantPool();
- ConstantCP cmr = (ConstantCP)cp.getConstant(index);
- ConstantNameAndType cnat = (ConstantNameAndType)cp.getConstant(cmr.getNameAndTypeIndex());
- return ((ConstantUtf8)cp.getConstant(cnat.getNameIndex())).getBytes();
+ public String getName( final ConstantPoolGen cpg ) {
+ final ConstantPool cp = cpg.getConstantPool();
+ final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex());
+ final ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex());
+ return ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getBytes();
}
- /** @return name of the referenced class/interface
- */
- public String getClassName(ConstantPoolGen cpg) {
- ConstantPool cp = cpg.getConstantPool();
- ConstantCP cmr = (ConstantCP)cp.getConstant(index);
- return cp.getConstantString(cmr.getClassIndex(), com.sun.org.apache.bcel.internal.Constants.CONSTANT_Class).replace('/', '.');
- }
- /** @return type of the referenced class/interface
+ /**
+ * @return name of the referenced class/interface
+ * @deprecated If the instruction references an array class,
+ * this method will return "java.lang.Object".
+ * For code generated by Java 1.5, this answer is
+ * sometimes wrong (e.g., if the "clone()" method is
+ * called on an array). A better idea is to use
+ * the {@link #getReferenceType(ConstantPoolGen)} method, which correctly distinguishes
+ * between class types and array types.
+ *
*/
- public ObjectType getClassType(ConstantPoolGen cpg) {
- return new ObjectType(getClassName(cpg));
+ @Deprecated
+ public String getClassName( final ConstantPoolGen cpg ) {
+ final ConstantPool cp = cpg.getConstantPool();
+ final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex());
+ final String className = cp.getConstantString(cmr.getClassIndex(), Const.CONSTANT_Class);
+ if (className.startsWith("[")) {
+ // Turn array classes into java.lang.Object.
+ return "java.lang.Object";
+ }
+ return className.replace('/', '.');
}
+
/** @return type of the referenced class/interface
+ * @deprecated If the instruction references an array class,
+ * the ObjectType returned will be invalid. Use
+ * getReferenceType() instead.
+ */
+ @Deprecated
+ public ObjectType getClassType( final ConstantPoolGen cpg ) {
+ return ObjectType.getInstance(getClassName(cpg));
+ }
+
+
+ /**
+ * Return the reference type representing the class, interface,
+ * or array class referenced by the instruction.
+ * @param cpg the ConstantPoolGen used to create the instruction
+ * @return an ObjectType (if the referenced class type is a class
+ * or interface), or an ArrayType (if the referenced class
+ * type is an array class)
+ */
+ public ReferenceType getReferenceType( final ConstantPoolGen cpg ) {
+ final ConstantPool cp = cpg.getConstantPool();
+ final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex());
+ String className = cp.getConstantString(cmr.getClassIndex(), Const.CONSTANT_Class);
+ if (className.startsWith("[")) {
+ return (ArrayType) Type.getType(className);
+ }
+ className = className.replace('/', '.');
+ return ObjectType.getInstance(className);
+ }
+
+
+ /**
+ * Get the ObjectType of the method return or field.
+ *
+ * @return type of the referenced class/interface
+ * @throws ClassGenException when the field is (or method returns) an array,
*/
- public ObjectType getLoadClassType(ConstantPoolGen cpg) {
- return getClassType(cpg);
+ @Override
+ public ObjectType getLoadClassType( final ConstantPoolGen cpg ) {
+ final ReferenceType rt = getReferenceType(cpg);
+ if(rt instanceof ObjectType) {
+ return (ObjectType)rt;
+ }
+ throw new ClassGenException(rt.getSignature() + " does not represent an ObjectType");
}
}
< prev index next >