diff options
author | chibash <chiba@javassist.org> | 2015-07-22 02:30:54 +0900 |
---|---|---|
committer | chibash <chiba@javassist.org> | 2015-07-22 02:30:54 +0900 |
commit | 2705a49f8fbe930cffa4358553e625071b3bf8ed (patch) | |
tree | da5cff06388f5952191d071099573621dd902f4d | |
parent | ecd733a236b3963c36ad869e05d14d1f49e99a92 (diff) | |
download | javassist-2705a49f8fbe930cffa4358553e625071b3bf8ed.tar.gz javassist-2705a49f8fbe930cffa4358553e625071b3bf8ed.zip |
added InnerClassAttribute#remove method
-rw-r--r-- | src/main/javassist/bytecode/InnerClassesAttribute.java | 34 | ||||
-rw-r--r-- | src/test/javassist/JvstTest5.java | 25 | ||||
-rw-r--r-- | src/test/test5/InnerClassRemove.java | 8 |
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; } +} |