aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2009-07-02 11:17:17 +0000
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2009-07-02 11:17:17 +0000
commitd8ba90667b8d2ca3ce409d355373aecaf48ae871 (patch)
tree65e7cb15554db75f0751f1c89ae096aa9e037661
parenta690c8bf872c9e5fe4e14b6095ddb81de01a34c4 (diff)
downloadjavassist-d8ba90667b8d2ca3ce409d355373aecaf48ae871.tar.gz
javassist-d8ba90667b8d2ca3ce409d355373aecaf48ae871.zip
fixed JIRA JASSIST-77
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@485 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
-rw-r--r--Readme.html2
-rw-r--r--src/main/javassist/bytecode/AttributeInfo.java31
-rw-r--r--src/main/javassist/bytecode/ClassFile.java6
-rw-r--r--src/main/javassist/bytecode/CodeAttribute.java9
-rw-r--r--src/main/javassist/bytecode/LocalVariableAttribute.java53
-rw-r--r--src/main/javassist/bytecode/LocalVariableTypeAttribute.java62
-rw-r--r--src/main/javassist/bytecode/SignatureAttribute.java113
7 files changed, 267 insertions, 9 deletions
diff --git a/Readme.html b/Readme.html
index 6317e262..7d5792aa 100644
--- a/Readme.html
+++ b/Readme.html
@@ -283,7 +283,7 @@ see javassist.Dump.
<p>-version 3.11
<ul>
- <li>JIRA JASSIST-67, 68, 74, 75, 76, 81, 83, 84, 85 were fixed.
+ <li>JIRA JASSIST-67, 68, 74, 75, 76, 77, 81, 83, 84, 85 were fixed.
<li>Now javassist.bytecode.CodeIterator can insert a gap into
a large method body more than 32KB. (JIRA JASSIST-79, 80)
</ul>
diff --git a/src/main/javassist/bytecode/AttributeInfo.java b/src/main/javassist/bytecode/AttributeInfo.java
index 67d1c48e..915f291f 100644
--- a/src/main/javassist/bytecode/AttributeInfo.java
+++ b/src/main/javassist/bytecode/AttributeInfo.java
@@ -21,6 +21,8 @@ import java.io.IOException;
import java.util.Map;
import java.util.LinkedList;
import java.util.ListIterator;
+import java.util.List;
+import java.util.Iterator;
// Note: if you define a new subclass of AttributeInfo, then
// update AttributeInfo.read(), .copy(), and (maybe) write().
@@ -92,9 +94,10 @@ public class AttributeInfo {
*/
if (nameStr.equals(LineNumberAttribute.tag))
return new LineNumberAttribute(cp, name, in);
- else if (nameStr.equals(LocalVariableAttribute.tag)
- || nameStr.equals(LocalVariableAttribute.typeTag))
+ else if (nameStr.equals(LocalVariableAttribute.tag))
return new LocalVariableAttribute(cp, name, in);
+ else if (nameStr.equals(LocalVariableTypeAttribute.tag))
+ return new LocalVariableTypeAttribute(cp, name, in);
else if (nameStr.equals(AnnotationsAttribute.visibleTag)
|| nameStr.equals(AnnotationsAttribute.invisibleTag)) {
// RuntimeVisibleAnnotations or RuntimeInvisibleAnnotations
@@ -243,4 +246,28 @@ public class AttributeInfo {
return newList;
}
+
+ /* The following two methods are used to implement
+ * ClassFile.renameClass().
+ * Only CodeAttribute and LocalVariableAttribute override
+ * this method.
+ */
+ void renameClass(String oldname, String newname) {}
+ void renameClass(Map classnames) {}
+
+ static void renameClass(List attributes, String oldname, String newname) {
+ Iterator iterator = attributes.iterator();
+ while (iterator.hasNext()) {
+ AttributeInfo ai = (AttributeInfo)iterator.next();
+ ai.renameClass(oldname, newname);
+ }
+ }
+
+ static void renameClass(List attributes, Map classnames) {
+ Iterator iterator = attributes.iterator();
+ while (iterator.hasNext()) {
+ AttributeInfo ai = (AttributeInfo)iterator.next();
+ ai.renameClass(classnames);
+ }
+ }
}
diff --git a/src/main/javassist/bytecode/ClassFile.java b/src/main/javassist/bytecode/ClassFile.java
index b2828f20..f03537c8 100644
--- a/src/main/javassist/bytecode/ClassFile.java
+++ b/src/main/javassist/bytecode/ClassFile.java
@@ -404,12 +404,14 @@ public final class ClassFile {
newname = Descriptor.toJvmName(newname);
constPool.renameClass(oldname, newname);
+ AttributeInfo.renameClass(attributes, oldname, newname);
list = methods;
n = list.size();
for (int i = 0; i < n; ++i) {
MethodInfo minfo = (MethodInfo)list.get(i);
String desc = minfo.getDescriptor();
minfo.setDescriptor(Descriptor.rename(desc, oldname, newname));
+ AttributeInfo.renameClass(minfo.getAttributes(), oldname, newname);
}
list = fields;
@@ -418,6 +420,7 @@ public final class ClassFile {
FieldInfo finfo = (FieldInfo)list.get(i);
String desc = finfo.getDescriptor();
finfo.setDescriptor(Descriptor.rename(desc, oldname, newname));
+ AttributeInfo.renameClass(finfo.getAttributes(), oldname, newname);
}
}
@@ -438,12 +441,14 @@ public final class ClassFile {
constPool.renameClass(classnames);
+ AttributeInfo.renameClass(attributes, classnames);
ArrayList list = methods;
int n = list.size();
for (int i = 0; i < n; ++i) {
MethodInfo minfo = (MethodInfo)list.get(i);
String desc = minfo.getDescriptor();
minfo.setDescriptor(Descriptor.rename(desc, classnames));
+ AttributeInfo.renameClass(minfo.getAttributes(), classnames);
}
list = fields;
@@ -452,6 +457,7 @@ public final class ClassFile {
FieldInfo finfo = (FieldInfo)list.get(i);
String desc = finfo.getDescriptor();
finfo.setDescriptor(Descriptor.rename(desc, classnames));
+ AttributeInfo.renameClass(finfo.getAttributes(), classnames);
}
}
diff --git a/src/main/javassist/bytecode/CodeAttribute.java b/src/main/javassist/bytecode/CodeAttribute.java
index 34a4fa5b..0f81ae59 100644
--- a/src/main/javassist/bytecode/CodeAttribute.java
+++ b/src/main/javassist/bytecode/CodeAttribute.java
@@ -20,6 +20,7 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.LinkedList;
+import java.util.Iterator;
import java.util.Map;
/**
@@ -191,6 +192,14 @@ public class CodeAttribute extends AttributeInfo implements Opcode {
throw new UnsupportedOperationException("CodeAttribute.set()");
}
+ void renameClass(String oldname, String newname) {
+ AttributeInfo.renameClass(attributes, oldname, newname);
+ }
+
+ void renameClass(Map classnames) {
+ AttributeInfo.renameClass(attributes, classnames);
+ }
+
/**
* Returns the name of the class declaring the method including
* this code attribute.
diff --git a/src/main/javassist/bytecode/LocalVariableAttribute.java b/src/main/javassist/bytecode/LocalVariableAttribute.java
index 80f96533..d01aa408 100644
--- a/src/main/javassist/bytecode/LocalVariableAttribute.java
+++ b/src/main/javassist/bytecode/LocalVariableAttribute.java
@@ -20,8 +20,7 @@ import java.io.IOException;
import java.util.Map;
/**
- * <code>LocalVariableTable_attribute</code> or
- * <code>LocalVariableTypeTable_attribute</code>.
+ * <code>LocalVariableTable_attribute</code>.
*/
public class LocalVariableAttribute extends AttributeInfo {
/**
@@ -38,7 +37,8 @@ public class LocalVariableAttribute extends AttributeInfo {
* Constructs an empty LocalVariableTable.
*/
public LocalVariableAttribute(ConstPool cp) {
- this(cp, tag);
+ super(cp, tag, new byte[2]);
+ ByteArray.write16bit(0, info, 0);
}
/**
@@ -50,6 +50,7 @@ public class LocalVariableAttribute extends AttributeInfo {
* @see #tag
* @see #typeTag
* @since 3.1
+ * @deprecated
*/
public LocalVariableAttribute(ConstPool cp, String name) {
super(cp, name, new byte[2]);
@@ -62,7 +63,7 @@ public class LocalVariableAttribute extends AttributeInfo {
super(cp, n, in);
}
- private LocalVariableAttribute(ConstPool cp, String name, byte[] i) {
+ LocalVariableAttribute(ConstPool cp, String name, byte[] i) {
super(cp, name, i);
}
@@ -91,6 +92,42 @@ public class LocalVariableAttribute extends AttributeInfo {
info = newInfo;
}
+ void renameClass(String oldname, String newname) {
+ ConstPool cp = getConstPool();
+ int n = tableLength();
+ for (int i = 0; i < n; ++i) {
+ int pos = i * 10 + 2;
+ int index = ByteArray.readU16bit(info, pos + 6);
+ if (index != 0) {
+ String desc = cp.getUtf8Info(index);
+ desc = renameEntry(desc, oldname, newname);
+ ByteArray.write16bit(cp.addUtf8Info(desc), info, pos + 6);
+ }
+ }
+ }
+
+ String renameEntry(String desc, String oldname, String newname) {
+ return Descriptor.rename(desc, oldname, newname);
+ }
+
+ void renameClass(Map classnames) {
+ ConstPool cp = getConstPool();
+ int n = tableLength();
+ for (int i = 0; i < n; ++i) {
+ int pos = i * 10 + 2;
+ int index = ByteArray.readU16bit(info, pos + 6);
+ if (index != 0) {
+ String desc = cp.getUtf8Info(index);
+ desc = renameEntry(desc, classnames);
+ ByteArray.write16bit(cp.addUtf8Info(desc), info, pos + 6);
+ }
+ }
+ }
+
+ String renameEntry(String desc, Map classnames) {
+ return Descriptor.rename(desc, classnames);
+ }
+
/**
* For each <code>local_variable_table[i].index</code>,
* this method increases <code>index</code> by <code>delta</code>.
@@ -257,8 +294,7 @@ public class LocalVariableAttribute extends AttributeInfo {
byte[] src = get();
byte[] dest = new byte[src.length];
ConstPool cp = getConstPool();
- LocalVariableAttribute attr
- = new LocalVariableAttribute(newCp, getName(), dest);
+ LocalVariableAttribute attr = makeThisAttr(newCp, dest);
int n = ByteArray.readU16bit(src, 0);
ByteArray.write16bit(n, dest, 0);
int j = 2;
@@ -289,4 +325,9 @@ public class LocalVariableAttribute extends AttributeInfo {
return attr;
}
+
+ // LocalVariableTypeAttribute overrides this method.
+ LocalVariableAttribute makeThisAttr(ConstPool cp, byte[] dest) {
+ return new LocalVariableAttribute(cp, tag, dest);
+ }
}
diff --git a/src/main/javassist/bytecode/LocalVariableTypeAttribute.java b/src/main/javassist/bytecode/LocalVariableTypeAttribute.java
new file mode 100644
index 00000000..d7ac098b
--- /dev/null
+++ b/src/main/javassist/bytecode/LocalVariableTypeAttribute.java
@@ -0,0 +1,62 @@
+/*
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. Alternatively, the contents of this file may be used under
+ * the terms of the GNU Lesser General Public License Version 2.1 or later.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ */
+
+package javassist.bytecode;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * <code>LocalVariableTypeTable_attribute</code>.
+ *
+ * @since 3.11
+ */
+public class LocalVariableTypeAttribute extends LocalVariableAttribute {
+ /**
+ * The name of the attribute <code>"LocalVariableTypeTable"</code>.
+ */
+ public static final String tag = LocalVariableAttribute.typeTag;
+
+ /**
+ * Constructs an empty LocalVariableTypeTable.
+ */
+ public LocalVariableTypeAttribute(ConstPool cp) {
+ super(cp, tag, new byte[2]);
+ ByteArray.write16bit(0, info, 0);
+ }
+
+ LocalVariableTypeAttribute(ConstPool cp, int n, DataInputStream in)
+ throws IOException
+ {
+ super(cp, n, in);
+ }
+
+ private LocalVariableTypeAttribute(ConstPool cp, byte[] dest) {
+ super(cp, tag, dest);
+ }
+
+ String renameEntry(String desc, String oldname, String newname) {
+ return SignatureAttribute.renameClass(desc, oldname, newname);
+ }
+
+ String renameEntry(String desc, Map classnames) {
+ return SignatureAttribute.renameClass(desc, classnames);
+ }
+
+ LocalVariableAttribute makeThisAttr(ConstPool cp, byte[] dest) {
+ return new LocalVariableTypeAttribute(cp, dest);
+ }
+}
diff --git a/src/main/javassist/bytecode/SignatureAttribute.java b/src/main/javassist/bytecode/SignatureAttribute.java
index 2c8f0e9b..267098f8 100644
--- a/src/main/javassist/bytecode/SignatureAttribute.java
+++ b/src/main/javassist/bytecode/SignatureAttribute.java
@@ -62,6 +62,18 @@ public class SignatureAttribute extends AttributeInfo {
}
/**
+ * Sets <code>signature_index</code> to the index of the given signature,
+ * which is added to a constant pool.
+ *
+ * @param sig new signature.
+ * @since 3.11
+ */
+ public void setSignature(String sig) {
+ int index = getConstPool().addUtf8Info(sig);
+ ByteArray.write16bit(index, info, 0);
+ }
+
+ /**
* Makes a copy. Class names are replaced according to the
* given <code>Map</code> object.
*
@@ -73,6 +85,107 @@ public class SignatureAttribute extends AttributeInfo {
return new SignatureAttribute(newCp, getSignature());
}
+ void renameClass(String oldname, String newname) {
+ String sig = renameClass(getSignature(), oldname, newname);
+ setSignature(sig);
+ }
+
+ void renameClass(Map classnames) {
+ String sig = renameClass(getSignature(), classnames);
+ setSignature(sig);
+ }
+
+ static String renameClass(String desc, String oldname, String newname) {
+ if (desc.indexOf(oldname) < 0)
+ return desc;
+
+ StringBuffer newdesc = new StringBuffer();
+ int head = 0;
+ int i = 0;
+ for (;;) {
+ int j = desc.indexOf('L', i);
+ if (j < 0)
+ break;
+
+ int k = j;
+ int p = 0;
+ char c;
+ boolean match = true;
+ try {
+ int len = oldname.length();
+ while (isNamePart(c = desc.charAt(++k)))
+ if (p >= len || c != oldname.charAt(p++))
+ match = false;
+ }
+ catch (IndexOutOfBoundsException e) { break; }
+ i = k + 1;
+ if (match && p == oldname.length()) {
+ newdesc.append(desc.substring(head, j));
+ newdesc.append('L');
+ newdesc.append(newname);
+ newdesc.append(c);
+ head = i;
+ }
+ }
+
+ if (head == 0)
+ return desc;
+ else {
+ int len = desc.length();
+ if (head < len)
+ newdesc.append(desc.substring(head, len));
+
+ return newdesc.toString();
+ }
+ }
+
+ static String renameClass(String desc, Map map) {
+ if (map == null)
+ return desc;
+
+ StringBuffer newdesc = new StringBuffer();
+ int head = 0;
+ int i = 0;
+ for (;;) {
+ int j = desc.indexOf('L', i);
+ if (j < 0)
+ break;
+
+ StringBuffer nameBuf = new StringBuffer();
+ int k = j;
+ char c;
+ try {
+ while (isNamePart(c = desc.charAt(++k)))
+ nameBuf.append(c);
+ }
+ catch (IndexOutOfBoundsException e) { break; }
+ i = k + 1;
+ String name = nameBuf.toString();
+ String name2 = (String)map.get(name);
+ if (name2 != null) {
+ newdesc.append(desc.substring(head, j));
+ newdesc.append('L');
+ newdesc.append(name2);
+ newdesc.append(c);
+ head = i;
+ }
+ }
+
+ if (head == 0)
+ return desc;
+ else {
+ int len = desc.length();
+ if (head < len)
+ newdesc.append(desc.substring(head, len));
+
+ return newdesc.toString();
+ }
+ }
+
+ private static boolean isNamePart(int c) {
+ return c != ';' && c != '<';
+ }
+
static private class Cursor {
int position = 0;