aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/javassist/bytecode/AnnotationsAttribute.java3
-rw-r--r--src/main/javassist/bytecode/AttributeInfo.java11
-rw-r--r--src/main/javassist/bytecode/ClassFile.java16
-rw-r--r--src/main/javassist/bytecode/FieldInfo.java16
-rw-r--r--src/main/javassist/bytecode/MethodInfo.java16
-rw-r--r--src/test/javassist/JvstTest5.java33
-rw-r--r--src/test/test5/RemoveAnnotation.java20
7 files changed, 112 insertions, 3 deletions
diff --git a/src/main/javassist/bytecode/AnnotationsAttribute.java b/src/main/javassist/bytecode/AnnotationsAttribute.java
index c4d5f3de..be69fe8b 100644
--- a/src/main/javassist/bytecode/AnnotationsAttribute.java
+++ b/src/main/javassist/bytecode/AnnotationsAttribute.java
@@ -215,9 +215,12 @@ public class AnnotationsAttribute extends AttributeInfo {
/**
* Removes an annotation by type.
+ * After removing an annotation, if {@link #numAnnotations()} returns 0,
+ * this annotations attribute has to be removed.
*
* @param type of annotation to remove
* @return whether an annotation with the given type has been removed
+ * @since 3.21
*/
public boolean removeAnnotation(String type) {
Annotation[] annotations = getAnnotations();
diff --git a/src/main/javassist/bytecode/AttributeInfo.java b/src/main/javassist/bytecode/AttributeInfo.java
index 9a1ac16c..5fd73281 100644
--- a/src/main/javassist/bytecode/AttributeInfo.java
+++ b/src/main/javassist/bytecode/AttributeInfo.java
@@ -231,16 +231,21 @@ public class AttributeInfo {
return null; // no such attribute
}
- static synchronized void remove(ArrayList list, String name) {
+ static synchronized AttributeInfo remove(ArrayList list, String name) {
if (list == null)
- return;
+ return null;
+ AttributeInfo removed = null;
ListIterator iterator = list.listIterator();
while (iterator.hasNext()) {
AttributeInfo ai = (AttributeInfo)iterator.next();
- if (ai.getName().equals(name))
+ if (ai.getName().equals(name)) {
iterator.remove();
+ removed = ai;
+ }
}
+
+ return removed;
}
static void writeAll(ArrayList list, DataOutputStream out)
diff --git a/src/main/javassist/bytecode/ClassFile.java b/src/main/javassist/bytecode/ClassFile.java
index 887ec7a3..f53ff149 100644
--- a/src/main/javassist/bytecode/ClassFile.java
+++ b/src/main/javassist/bytecode/ClassFile.java
@@ -761,6 +761,11 @@ public final class ClassFile {
* Returns the attribute with the specified name. If there are multiple
* attributes with that name, this method returns either of them. It
* returns null if the specified attributed is not found.
+ *
+ * <p>An attribute name can be obtained by, for example,
+ * {@link AnnotationsAttribute#visibleTab} or
+ * {@link AnnotationsAttribute#invisibleTab}.
+ * </p>
*
* @param name attribute name
* @see #getAttributes()
@@ -778,6 +783,17 @@ public final class ClassFile {
}
/**
+ * Removes an attribute with the specified name.
+ *
+ * @param name attribute name.
+ * @return the removed attribute or null.
+ * @since 3.21
+ */
+ public AttributeInfo removeAttribute(String name) {
+ return AttributeInfo.remove(attributes, name);
+ }
+
+ /**
* Appends an attribute. If there is already an attribute with the same
* name, the new one substitutes for it.
*
diff --git a/src/main/javassist/bytecode/FieldInfo.java b/src/main/javassist/bytecode/FieldInfo.java
index cbba0a85..0e2f76a5 100644
--- a/src/main/javassist/bytecode/FieldInfo.java
+++ b/src/main/javassist/bytecode/FieldInfo.java
@@ -231,6 +231,11 @@ public final class FieldInfo {
* Returns the attribute with the specified name.
* It returns null if the specified attribute is not found.
*
+ * <p>An attribute name can be obtained by, for example,
+ * {@link AnnotationsAttribute#visibleTab} or
+ * {@link AnnotationsAttribute#invisibleTab}.
+ * </p>
+ *
* @param name attribute name
* @see #getAttributes()
*/
@@ -239,6 +244,17 @@ public final class FieldInfo {
}
/**
+ * Removes an attribute with the specified name.
+ *
+ * @param name attribute name.
+ * @return the removed attribute or null.
+ * @since 3.21
+ */
+ public AttributeInfo removeAttribute(String name) {
+ return AttributeInfo.remove(attribute, name);
+ }
+
+ /**
* Appends an attribute. If there is already an attribute with
* the same name, the new one substitutes for it.
*
diff --git a/src/main/javassist/bytecode/MethodInfo.java b/src/main/javassist/bytecode/MethodInfo.java
index 4b8c1c4d..72642268 100644
--- a/src/main/javassist/bytecode/MethodInfo.java
+++ b/src/main/javassist/bytecode/MethodInfo.java
@@ -315,6 +315,11 @@ public class MethodInfo {
* Returns the attribute with the specified name. If it is not found, this
* method returns null.
*
+ * <p>An attribute name can be obtained by, for example,
+ * {@link AnnotationsAttribute#visibleTab} or
+ * {@link AnnotationsAttribute#invisibleTab}.
+ * </p>
+ *
* @param name attribute name
* @return an <code>AttributeInfo</code> object or null.
* @see #getAttributes()
@@ -324,6 +329,17 @@ public class MethodInfo {
}
/**
+ * Removes an attribute with the specified name.
+ *
+ * @param name attribute name.
+ * @return the removed attribute or null.
+ * @since 3.21
+ */
+ public AttributeInfo removeAttribute(String name) {
+ return AttributeInfo.remove(attribute, name);
+ }
+
+ /**
* Appends an attribute. If there is already an attribute with the same
* name, the new one substitutes for it.
*
diff --git a/src/test/javassist/JvstTest5.java b/src/test/javassist/JvstTest5.java
index 779df525..c20a85f2 100644
--- a/src/test/javassist/JvstTest5.java
+++ b/src/test/javassist/JvstTest5.java
@@ -4,6 +4,7 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.TypeVariable;
import javassist.bytecode.AnnotationsAttribute;
+import javassist.bytecode.AttributeInfo;
import javassist.bytecode.ClassFile;
import javassist.bytecode.ConstPool;
import javassist.bytecode.InnerClassesAttribute;
@@ -251,4 +252,36 @@ public class JvstTest5 extends JvstTestRoot {
fail();
} catch (CannotCompileException e) {}
}
+
+ public void testRemoveAnnotatino() throws Exception {
+ CtClass cc = sloader.get("test5.RemoveAnnotation");
+ AnnotationsAttribute aa
+ = (AnnotationsAttribute)cc.getClassFile().getAttribute(AnnotationsAttribute.invisibleTag);
+ assertTrue(aa.removeAnnotation("test5.RemoveAnno1"));
+ AttributeInfo ai = cc.getClassFile().removeAttribute(AnnotationsAttribute.invisibleTag);
+ assertEquals(ai.getName(), AnnotationsAttribute.invisibleTag);
+
+ CtMethod foo = cc.getDeclaredMethod("foo");
+ AnnotationsAttribute aa2 = (AnnotationsAttribute)foo.getMethodInfo().getAttribute(AnnotationsAttribute.invisibleTag);
+ assertTrue(aa2.removeAnnotation("test5.RemoveAnno1"));
+
+ CtMethod bar = cc.getDeclaredMethod("bar");
+ AnnotationsAttribute aa3 = (AnnotationsAttribute)bar.getMethodInfo().getAttribute(AnnotationsAttribute.invisibleTag);
+ assertFalse(aa3.removeAnnotation("test5.RemoveAnno1"));
+ assertTrue(aa3.removeAnnotation("test5.RemoveAnno2"));
+ AttributeInfo ai2 = bar.getMethodInfo().removeAttribute(AnnotationsAttribute.invisibleTag);
+ assertEquals(ai2.getName(), AnnotationsAttribute.invisibleTag);
+
+ CtMethod run = cc.getDeclaredMethod("run");
+ AttributeInfo ai3 = run.getMethodInfo().removeAttribute(AnnotationsAttribute.invisibleTag);
+ assertNull(ai3);
+
+ CtField baz = cc.getDeclaredField("baz");
+ AttributeInfo ai4 = baz.getFieldInfo().removeAttribute(AnnotationsAttribute.invisibleTag);
+ assertEquals(ai4.getName(), AnnotationsAttribute.invisibleTag);
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(3, invoke(obj, "run"));
+ }
}
diff --git a/src/test/test5/RemoveAnnotation.java b/src/test/test5/RemoveAnnotation.java
new file mode 100644
index 00000000..97f75253
--- /dev/null
+++ b/src/test/test5/RemoveAnnotation.java
@@ -0,0 +1,20 @@
+package test5;
+
+@interface RemoveAnno1 {}
+
+@interface RemoveAnno2 {
+ int foo() default 3;
+}
+
+@RemoveAnno1 public class RemoveAnnotation {
+ @RemoveAnno1 @RemoveAnno2(foo=4)
+ int foo() { return 1; }
+
+ @RemoveAnno2
+ int bar() { return 2; }
+
+ @RemoveAnno1
+ int baz = 10;
+
+ public int run() { return foo() + bar(); }
+}