aboutsummaryrefslogtreecommitdiff
path: root/src/main/javassist/bytecode/TypeAnnotationsAttribute.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/javassist/bytecode/TypeAnnotationsAttribute.java')
-rw-r--r--src/main/javassist/bytecode/TypeAnnotationsAttribute.java381
1 files changed, 381 insertions, 0 deletions
diff --git a/src/main/javassist/bytecode/TypeAnnotationsAttribute.java b/src/main/javassist/bytecode/TypeAnnotationsAttribute.java
new file mode 100644
index 0000000..86fea72
--- /dev/null
+++ b/src/main/javassist/bytecode/TypeAnnotationsAttribute.java
@@ -0,0 +1,381 @@
+package javassist.bytecode;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javassist.bytecode.annotation.TypeAnnotationsWriter;
+
+/**
+ * A class representing
+ * {@code RuntimeVisibleTypeAnnotations} attribute and
+ * {@code RuntimeInvisibleTypeAnnotations} attribute.
+ *
+ * @since 3.19
+ */
+public class TypeAnnotationsAttribute extends AttributeInfo {
+ /**
+ * The name of the {@code RuntimeVisibleTypeAnnotations} attribute.
+ */
+ public static final String visibleTag = "RuntimeVisibleTypeAnnotations";
+
+ /**
+ * The name of the {@code RuntimeInvisibleTypeAnnotations} attribute.
+ */
+ public static final String invisibleTag = "RuntimeInvisibleTypeAnnotations";
+
+ /**
+ * Constructs a <code>Runtime(In)VisibleTypeAnnotations_attribute</code>.
+ *
+ * @param cp constant pool
+ * @param attrname attribute name (<code>visibleTag</code> or
+ * <code>invisibleTag</code>).
+ * @param info the contents of this attribute. It does not
+ * include <code>attribute_name_index</code> or
+ * <code>attribute_length</code>.
+ */
+ public TypeAnnotationsAttribute(ConstPool cp, String attrname, byte[] info) {
+ super(cp, attrname, info);
+ }
+
+ /**
+ * @param n the attribute name.
+ */
+ TypeAnnotationsAttribute(ConstPool cp, int n, DataInputStream in)
+ throws IOException
+ {
+ super(cp, n, in);
+ }
+
+ /**
+ * Returns <code>num_annotations</code>.
+ */
+ public int numAnnotations() {
+ return ByteArray.readU16bit(info, 0);
+ }
+
+ /**
+ * Copies this attribute and returns a new copy.
+ */
+ @Override
+ public AttributeInfo copy(ConstPool newCp, Map<String,String> classnames) {
+ Copier copier = new Copier(info, constPool, newCp, classnames);
+ try {
+ copier.annotationArray();
+ return new TypeAnnotationsAttribute(newCp, getName(), copier.close());
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * @param oldname a JVM class name.
+ * @param newname a JVM class name.
+ */
+ @Override
+ void renameClass(String oldname, String newname) {
+ Map<String,String> map = new HashMap<String,String>();
+ map.put(oldname, newname);
+ renameClass(map);
+ }
+
+ @Override
+ void renameClass(Map<String,String> classnames) {
+ Renamer renamer = new Renamer(info, getConstPool(), classnames);
+ try {
+ renamer.annotationArray();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ void getRefClasses(Map<String,String> classnames) { renameClass(classnames); }
+
+ /**
+ * To visit each elements of the type annotation attribute,
+ * call {@code annotationArray()}.
+ *
+ * @see #annotationArray()
+ */
+ static class TAWalker extends AnnotationsAttribute.Walker {
+ SubWalker subWalker;
+
+ TAWalker(byte[] attrInfo) {
+ super(attrInfo);
+ subWalker = new SubWalker(attrInfo);
+ }
+
+ @Override
+ int annotationArray(int pos, int num) throws Exception {
+ for (int i = 0; i < num; i++) {
+ int targetType = info[pos] & 0xff;
+ pos = subWalker.targetInfo(pos + 1, targetType);
+ pos = subWalker.typePath(pos);
+ pos = annotation(pos);
+ }
+
+ return pos;
+ }
+ }
+
+ static class SubWalker {
+ byte[] info;
+
+ SubWalker(byte[] attrInfo) {
+ info = attrInfo;
+ }
+
+ final int targetInfo(int pos, int type) throws Exception {
+ switch (type) {
+ case 0x00:
+ case 0x01: {
+ int index = info[pos] & 0xff;
+ typeParameterTarget(pos, type, index);
+ return pos + 1; }
+ case 0x10: {
+ int index = ByteArray.readU16bit(info, pos);
+ supertypeTarget(pos, index);
+ return pos + 2; }
+ case 0x11:
+ case 0x12: {
+ int param = info[pos] & 0xff;
+ int bound = info[pos + 1] & 0xff;
+ typeParameterBoundTarget(pos, type, param, bound);
+ return pos + 2; }
+ case 0x13:
+ case 0x14:
+ case 0x15:
+ emptyTarget(pos, type);
+ return pos;
+ case 0x16: {
+ int index = info[pos] & 0xff;
+ formalParameterTarget(pos, index);
+ return pos + 1; }
+ case 0x17: {
+ int index = ByteArray.readU16bit(info, pos);
+ throwsTarget(pos, index);
+ return pos + 2; }
+ case 0x40:
+ case 0x41: {
+ int len = ByteArray.readU16bit(info, pos);
+ return localvarTarget(pos + 2, type, len); }
+ case 0x42: {
+ int index = ByteArray.readU16bit(info, pos);
+ catchTarget(pos, index);
+ return pos + 2; }
+ case 0x43:
+ case 0x44:
+ case 0x45:
+ case 0x46: {
+ int offset = ByteArray.readU16bit(info, pos);
+ offsetTarget(pos, type, offset);
+ return pos + 2; }
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4a:
+ case 0x4b: {
+ int offset = ByteArray.readU16bit(info, pos);
+ int index = info[pos + 2] & 0xff;
+ typeArgumentTarget(pos, type, offset, index);
+ return pos + 3; }
+ default:
+ throw new RuntimeException("invalid target type: " + type);
+ }
+ }
+
+ void typeParameterTarget(int pos, int targetType, int typeParameterIndex)
+ throws Exception {}
+
+ void supertypeTarget(int pos, int superTypeIndex) throws Exception {}
+
+ void typeParameterBoundTarget(int pos, int targetType, int typeParameterIndex,
+ int boundIndex) throws Exception {}
+
+ void emptyTarget(int pos, int targetType) throws Exception {}
+
+ void formalParameterTarget(int pos, int formalParameterIndex) throws Exception {}
+
+ void throwsTarget(int pos, int throwsTypeIndex) throws Exception {}
+
+ int localvarTarget(int pos, int targetType, int tableLength) throws Exception {
+ for (int i = 0; i < tableLength; i++) {
+ int start = ByteArray.readU16bit(info, pos);
+ int length = ByteArray.readU16bit(info, pos + 2);
+ int index = ByteArray.readU16bit(info, pos + 4);
+ localvarTarget(pos, targetType, start, length, index);
+ pos += 6;
+ }
+
+ return pos;
+ }
+
+ void localvarTarget(int pos, int targetType, int startPc, int length, int index)
+ throws Exception {}
+
+ void catchTarget(int pos, int exceptionTableIndex) throws Exception {}
+
+ void offsetTarget(int pos, int targetType, int offset) throws Exception {}
+
+ void typeArgumentTarget(int pos, int targetType, int offset, int typeArgumentIndex)
+ throws Exception {}
+
+ final int typePath(int pos) throws Exception {
+ int len = info[pos++] & 0xff;
+ return typePath(pos, len);
+ }
+
+ int typePath(int pos, int pathLength) throws Exception {
+ for (int i = 0; i < pathLength; i++) {
+ int kind = info[pos] & 0xff;
+ int index = info[pos + 1] & 0xff;
+ typePath(pos, kind, index);
+ pos += 2;
+ }
+
+ return pos;
+ }
+
+ void typePath(int pos, int typePathKind, int typeArgumentIndex) throws Exception {}
+ }
+
+ static class Renamer extends AnnotationsAttribute.Renamer {
+ SubWalker sub;
+
+ Renamer(byte[] attrInfo, ConstPool cp, Map<String,String> map) {
+ super(attrInfo, cp, map);
+ sub = new SubWalker(attrInfo);
+ }
+
+ @Override
+ int annotationArray(int pos, int num) throws Exception {
+ for (int i = 0; i < num; i++) {
+ int targetType = info[pos] & 0xff;
+ pos = sub.targetInfo(pos + 1, targetType);
+ pos = sub.typePath(pos);
+ pos = annotation(pos);
+ }
+
+ return pos;
+ }
+ }
+
+ static class Copier extends AnnotationsAttribute.Copier {
+ SubCopier sub;
+
+ Copier(byte[] attrInfo, ConstPool src, ConstPool dest, Map<String,String> map) {
+ super(attrInfo, src, dest, map, false);
+ TypeAnnotationsWriter w = new TypeAnnotationsWriter(output, dest);
+ writer = w;
+ sub = new SubCopier(attrInfo, src, dest, map, w);
+ }
+
+ @Override
+ int annotationArray(int pos, int num) throws Exception {
+ writer.numAnnotations(num);
+ for (int i = 0; i < num; i++) {
+ int targetType = info[pos] & 0xff;
+ pos = sub.targetInfo(pos + 1, targetType);
+ pos = sub.typePath(pos);
+ pos = annotation(pos);
+ }
+
+ return pos;
+ }
+ }
+
+ static class SubCopier extends SubWalker {
+ ConstPool srcPool, destPool;
+ Map<String,String> classnames;
+ TypeAnnotationsWriter writer;
+
+ SubCopier(byte[] attrInfo, ConstPool src, ConstPool dest,
+ Map<String,String> map, TypeAnnotationsWriter w)
+ {
+ super(attrInfo);
+ srcPool = src;
+ destPool = dest;
+ classnames = map;
+ writer = w;
+ }
+
+ @Override
+ void typeParameterTarget(int pos, int targetType, int typeParameterIndex)
+ throws Exception
+ {
+ writer.typeParameterTarget(targetType, typeParameterIndex);
+ }
+
+ @Override
+ void supertypeTarget(int pos, int superTypeIndex) throws Exception {
+ writer.supertypeTarget(superTypeIndex);
+ }
+
+ @Override
+ void typeParameterBoundTarget(int pos, int targetType, int typeParameterIndex,
+ int boundIndex)
+ throws Exception
+ {
+ writer.typeParameterBoundTarget(targetType, typeParameterIndex, boundIndex);
+ }
+
+ @Override
+ void emptyTarget(int pos, int targetType) throws Exception {
+ writer.emptyTarget(targetType);
+ }
+
+ @Override
+ void formalParameterTarget(int pos, int formalParameterIndex) throws Exception {
+ writer.formalParameterTarget(formalParameterIndex);
+ }
+
+ @Override
+ void throwsTarget(int pos, int throwsTypeIndex) throws Exception {
+ writer.throwsTarget(throwsTypeIndex);
+ }
+
+ @Override
+ int localvarTarget(int pos, int targetType, int tableLength) throws Exception {
+ writer.localVarTarget(targetType, tableLength);
+ return super.localvarTarget(pos, targetType, tableLength);
+ }
+
+ @Override
+ void localvarTarget(int pos, int targetType, int startPc, int length, int index)
+ throws Exception
+ {
+ writer.localVarTargetTable(startPc, length, index);
+ }
+
+ @Override
+ void catchTarget(int pos, int exceptionTableIndex) throws Exception {
+ writer.catchTarget(exceptionTableIndex);
+ }
+
+ @Override
+ void offsetTarget(int pos, int targetType, int offset) throws Exception {
+ writer.offsetTarget(targetType, offset);
+ }
+
+ @Override
+ void typeArgumentTarget(int pos, int targetType, int offset, int typeArgumentIndex)
+ throws Exception
+ {
+ writer.typeArgumentTarget(targetType, offset, typeArgumentIndex);
+ }
+
+ @Override
+ int typePath(int pos, int pathLength) throws Exception {
+ writer.typePath(pathLength);
+ return super.typePath(pos, pathLength);
+ }
+
+ @Override
+ void typePath(int pos, int typePathKind, int typeArgumentIndex) throws Exception {
+ writer.typePathPath(typePathKind, typeArgumentIndex);
+ }
+ }
+}