aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/javassist/bytecode
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/javassist/bytecode')
-rw-r--r--src/main/javassist/bytecode/ClassFile.java56
-rw-r--r--src/main/javassist/bytecode/MethodInfo.java36
2 files changed, 83 insertions, 9 deletions
diff --git a/src/main/javassist/bytecode/ClassFile.java b/src/main/javassist/bytecode/ClassFile.java
index 3d743d7b..73cdc6ec 100644
--- a/src/main/javassist/bytecode/ClassFile.java
+++ b/src/main/javassist/bytecode/ClassFile.java
@@ -46,10 +46,28 @@ public final class ClassFile {
String cachedSuperclass;
/**
+ * The major version number of class files
+ * for JDK 1.3.
+ */
+ public static final int JAVA_3 = 47;
+
+ /**
+ * The major version number of class files
+ * for JDK 1.5.
+ */
+ public static final int JAVA_5 = 49;
+
+ /**
+ * The major version number of class files
+ * for JDK 1.6.
+ */
+ public static final int JAVA_6 = 50;
+
+ /**
* The major version number of class files created
* from scratch. The value is 47 (JDK 1.3).
*/
- public static final int MAJOR_VERSION = 47;
+ public static final int MAJOR_VERSION = JAVA_3;
/**
* Constructs a class file from a byte stream.
@@ -540,6 +558,8 @@ public final class ClassFile {
/**
* Appends a method to the class.
+ * If there is a bridge method with the same name and signature,
+ * then the bridge method is removed before a new method is added.
*
* @throws DuplicateMemberException when the method is already included.
*/
@@ -558,20 +578,38 @@ public final class ClassFile {
String name = newMinfo.getName();
String descriptor = newMinfo.getDescriptor();
ListIterator it = methods.listIterator(0);
- while (it.hasNext()) {
- MethodInfo minfo = (MethodInfo)it.next();
- if (minfo.getName().equals(name)
- && notBridgeMethod(minfo) && notBridgeMethod(newMinfo)
- && Descriptor.eqParamTypes(minfo.getDescriptor(),
- descriptor))
+ while (it.hasNext())
+ if (isDuplicated(newMinfo, name, descriptor, (MethodInfo)it.next(), it))
throw new DuplicateMemberException("duplicate method: " + name
- + " in " + this.getName());
+ + " in " + this.getName());
+ }
+
+ private static boolean isDuplicated(MethodInfo newMethod, String newName,
+ String newDesc, MethodInfo minfo,
+ ListIterator it)
+ {
+ if (!minfo.getName().equals(newName))
+ return false;
+
+ String desc = minfo.getDescriptor();
+ if (!Descriptor.eqParamTypes(desc, newDesc))
+ return false;
+
+ if (desc.equals(newDesc)) {
+ if (notBridgeMethod(minfo))
+ return true;
+ else {
+ it.remove();
+ return false;
+ }
}
+ else
+ return notBridgeMethod(minfo) && notBridgeMethod(newMethod);
}
/* For a bridge method, see Sec. 15.12.4.5 of JLS 3rd Ed.
*/
- private boolean notBridgeMethod(MethodInfo minfo) {
+ private static boolean notBridgeMethod(MethodInfo minfo) {
return (minfo.getAccessFlags() & AccessFlag.BRIDGE) == 0;
}
diff --git a/src/main/javassist/bytecode/MethodInfo.java b/src/main/javassist/bytecode/MethodInfo.java
index 8d0cce10..6e945570 100644
--- a/src/main/javassist/bytecode/MethodInfo.java
+++ b/src/main/javassist/bytecode/MethodInfo.java
@@ -21,6 +21,8 @@ import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import javassist.ClassPool;
+import javassist.bytecode.stackmap.MapMaker;
/**
* <code>method_info</code> structure.
@@ -371,6 +373,40 @@ public final class MethodInfo {
}
/**
+ * Rebuilds a stack map table if the class file is for Java 6
+ * or later. Java 5 or older Java VMs do not recognize a stack
+ * map table.
+ *
+ * @param pool used for making type hierarchy.
+ * @param cf rebuild if this class file is for Java 6 or later.
+ * @see #rebuildStackMap(ClassPool)
+ * @since 3.6
+ */
+ public void rebuildStackMapIf6(ClassPool pool, ClassFile cf)
+ throws BadBytecode
+ {
+ if (cf.getMajorVersion() >= ClassFile.JAVA_6)
+ rebuildStackMap(pool);
+ }
+
+ /**
+ * Rebuilds a stack map table. If no stack map table is included,
+ * a new one is created. If this <code>MethodInfo</code> does not
+ * include a code attribute, nothing happens.
+ *
+ * @param pool used for making type hierarchy.
+ * @see StackMapTable
+ * @since 3.6
+ */
+ public void rebuildStackMap(ClassPool pool) throws BadBytecode {
+ CodeAttribute ca = getCodeAttribute();
+ if (ca != null) {
+ StackMapTable smt = MapMaker.make(pool, this);
+ ca.setAttribute(smt);
+ }
+ }
+
+ /**
* Returns the line number of the source line corresponding to the specified
* bytecode contained in this method.
*