aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchibash <chiba@javassist.org>2015-07-22 02:30:54 +0900
committerchibash <chiba@javassist.org>2015-07-22 02:30:54 +0900
commit2705a49f8fbe930cffa4358553e625071b3bf8ed (patch)
treeda5cff06388f5952191d071099573621dd902f4d
parentecd733a236b3963c36ad869e05d14d1f49e99a92 (diff)
downloadjavassist-2705a49f8fbe930cffa4358553e625071b3bf8ed.tar.gz
javassist-2705a49f8fbe930cffa4358553e625071b3bf8ed.zip
added InnerClassAttribute#remove method
-rw-r--r--src/main/javassist/bytecode/InnerClassesAttribute.java34
-rw-r--r--src/test/javassist/JvstTest5.java25
-rw-r--r--src/test/test5/InnerClassRemove.java8
3 files changed, 67 insertions, 0 deletions
diff --git a/src/main/javassist/bytecode/InnerClassesAttribute.java b/src/main/javassist/bytecode/InnerClassesAttribute.java
index 5dffd6ee..cf021791 100644
--- a/src/main/javassist/bytecode/InnerClassesAttribute.java
+++ b/src/main/javassist/bytecode/InnerClassesAttribute.java
@@ -198,6 +198,40 @@ public class InnerClassesAttribute extends AttributeInfo {
}
/**
+ * Removes the {@code nth} entry. It does not eliminate
+ * constant pool items that the removed entry refers to.
+ * {@link ClassFile#compact()} should be executed to remove
+ * these unnecessary items.
+ *
+ * @param nth 0, 1, 2, ...
+ * @return the number of items after the removal.
+ * @see ClassFile#compact()
+ */
+ public int remove(int nth) {
+ byte[] data = get();
+ int len = data.length;
+ if (len < 10)
+ return 0;
+
+ int n = ByteArray.readU16bit(data, 0);
+ int nthPos = 2 + nth * 8;
+ if (n <= nth)
+ return n;
+
+ byte[] newData = new byte[len - 8];
+ ByteArray.write16bit(n - 1, newData, 0);
+ int i = 2, j = 2;
+ while (i < len)
+ if (i == nthPos)
+ i += 8;
+ else
+ newData[j++] = data[i++];
+
+ set(newData);
+ return n - 1;
+ }
+
+ /**
* Makes a copy. Class names are replaced according to the
* given <code>Map</code> object.
*
diff --git a/src/test/javassist/JvstTest5.java b/src/test/javassist/JvstTest5.java
index cefc84fc..6afb41a2 100644
--- a/src/test/javassist/JvstTest5.java
+++ b/src/test/javassist/JvstTest5.java
@@ -3,6 +3,9 @@ package javassist;
import java.lang.annotation.Annotation;
import java.lang.reflect.TypeVariable;
+import javassist.bytecode.ClassFile;
+import javassist.bytecode.InnerClassesAttribute;
+
public class JvstTest5 extends JvstTestRoot {
public JvstTest5(String name) {
super(name);
@@ -100,4 +103,26 @@ public class JvstTest5 extends JvstTestRoot {
Object obj = make(cc.getName());
assertEquals(1, invoke(obj, "run"));
}
+
+ public void testInnerClassAttributeRemove() throws Exception {
+ CtClass cc = sloader.get("test5.InnerClassRemove");
+ ClassFile cf = cc.getClassFile();
+ InnerClassesAttribute ica = (InnerClassesAttribute)cf.getAttribute(InnerClassesAttribute.tag);
+ String second = ica.innerClass(1);
+ String secondName = ica.innerName(1);
+ String third = ica.innerClass(2);
+ String thirdName = ica.innerName(2);
+ assertEquals(3, ica.remove(3));
+ assertEquals(2, ica.remove(0));
+ assertEquals(second, ica.innerClass(0));
+ assertEquals(secondName, ica.innerName(0));
+ assertEquals(third, ica.innerClass(1));
+ assertEquals(thirdName, ica.innerName(1));
+ assertEquals(1, ica.remove(1));
+ assertEquals(second, ica.innerClass(0));
+ assertEquals(secondName, ica.innerName(0));
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(1, invoke(obj, "run"));
+ }
}
diff --git a/src/test/test5/InnerClassRemove.java b/src/test/test5/InnerClassRemove.java
new file mode 100644
index 00000000..8fff676b
--- /dev/null
+++ b/src/test/test5/InnerClassRemove.java
@@ -0,0 +1,8 @@
+package test5;
+
+public class InnerClassRemove {
+ public class A { int a; }
+ class B { int b; }
+ static class C { int c; }
+ public int run() { return 1; }
+}