You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TypeAnnotationsAttribute.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. package javassist.bytecode;
  2. import java.io.DataInputStream;
  3. import java.io.IOException;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6. import javassist.bytecode.annotation.TypeAnnotationsWriter;
  7. /**
  8. * A class representing
  9. * {@code RuntimeVisibleTypeAnnotations} attribute and
  10. * {@code RuntimeInvisibleTypeAnnotations} attribute.
  11. *
  12. * @since 3.19
  13. */
  14. public class TypeAnnotationsAttribute extends AttributeInfo {
  15. /**
  16. * The name of the {@code RuntimeVisibleTypeAnnotations} attribute.
  17. */
  18. public static final String visibleTag = "RuntimeVisibleTypeAnnotations";
  19. /**
  20. * The name of the {@code RuntimeInvisibleTypeAnnotations} attribute.
  21. */
  22. public static final String invisibleTag = "RuntimeInvisibleTypeAnnotations";
  23. /**
  24. * Constructs a <code>Runtime(In)VisibleTypeAnnotations_attribute</code>.
  25. *
  26. * @param cp constant pool
  27. * @param attrname attribute name (<code>visibleTag</code> or
  28. * <code>invisibleTag</code>).
  29. * @param info the contents of this attribute. It does not
  30. * include <code>attribute_name_index</code> or
  31. * <code>attribute_length</code>.
  32. */
  33. public TypeAnnotationsAttribute(ConstPool cp, String attrname, byte[] info) {
  34. super(cp, attrname, info);
  35. }
  36. /**
  37. * @param n the attribute name.
  38. */
  39. TypeAnnotationsAttribute(ConstPool cp, int n, DataInputStream in)
  40. throws IOException
  41. {
  42. super(cp, n, in);
  43. }
  44. /**
  45. * Returns <code>num_annotations</code>.
  46. */
  47. public int numAnnotations() {
  48. return ByteArray.readU16bit(info, 0);
  49. }
  50. /**
  51. * Copies this attribute and returns a new copy.
  52. */
  53. public AttributeInfo copy(ConstPool newCp, Map classnames) {
  54. Copier copier = new Copier(info, constPool, newCp, classnames);
  55. try {
  56. copier.annotationArray();
  57. return new TypeAnnotationsAttribute(newCp, getName(), copier.close());
  58. }
  59. catch (Exception e) {
  60. throw new RuntimeException(e);
  61. }
  62. }
  63. /**
  64. * @param oldname a JVM class name.
  65. * @param newname a JVM class name.
  66. */
  67. void renameClass(String oldname, String newname) {
  68. HashMap map = new HashMap();
  69. map.put(oldname, newname);
  70. renameClass(map);
  71. }
  72. void renameClass(Map classnames) {
  73. Renamer renamer = new Renamer(info, getConstPool(), classnames);
  74. try {
  75. renamer.annotationArray();
  76. } catch (Exception e) {
  77. throw new RuntimeException(e);
  78. }
  79. }
  80. void getRefClasses(Map classnames) { renameClass(classnames); }
  81. /**
  82. * To visit each elements of the type annotation attribute,
  83. * call {@code annotationArray()}.
  84. *
  85. * @see #annotationArray()
  86. */
  87. static class TAWalker extends AnnotationsAttribute.Walker {
  88. SubWalker subWalker;
  89. TAWalker(byte[] attrInfo) {
  90. super(attrInfo);
  91. subWalker = new SubWalker(attrInfo);
  92. }
  93. int annotationArray(int pos, int num) throws Exception {
  94. for (int i = 0; i < num; i++) {
  95. int targetType = info[pos] & 0xff;
  96. pos = subWalker.targetInfo(pos + 1, targetType);
  97. pos = subWalker.typePath(pos);
  98. pos = annotation(pos);
  99. }
  100. return pos;
  101. }
  102. }
  103. static class SubWalker {
  104. byte[] info;
  105. SubWalker(byte[] attrInfo) {
  106. info = attrInfo;
  107. }
  108. final int targetInfo(int pos, int type) throws Exception {
  109. switch (type) {
  110. case 0x00:
  111. case 0x01: {
  112. int index = info[pos] & 0xff;
  113. typeParameterTarget(pos, type, index);
  114. return pos + 1; }
  115. case 0x10: {
  116. int index = ByteArray.readU16bit(info, pos);
  117. supertypeTarget(pos, index);
  118. return pos + 2; }
  119. case 0x11:
  120. case 0x12: {
  121. int param = info[pos] & 0xff;
  122. int bound = info[pos + 1] & 0xff;
  123. typeParameterBoundTarget(pos, type, param, bound);
  124. return pos + 2; }
  125. case 0x13:
  126. case 0x14:
  127. case 0x15:
  128. emptyTarget(pos, type);
  129. return pos;
  130. case 0x16: {
  131. int index = info[pos] & 0xff;
  132. formalParameterTarget(pos, index);
  133. return pos + 1; }
  134. case 0x17: {
  135. int index = ByteArray.readU16bit(info, pos);
  136. throwsTarget(pos, index);
  137. return pos + 2; }
  138. case 0x40:
  139. case 0x41: {
  140. int len = ByteArray.readU16bit(info, pos);
  141. return localvarTarget(pos + 2, type, len); }
  142. case 0x42: {
  143. int index = ByteArray.readU16bit(info, pos);
  144. catchTarget(pos, index);
  145. return pos + 2; }
  146. case 0x43:
  147. case 0x44:
  148. case 0x45:
  149. case 0x46: {
  150. int offset = ByteArray.readU16bit(info, pos);
  151. offsetTarget(pos, type, offset);
  152. return pos + 2; }
  153. case 0x47:
  154. case 0x48:
  155. case 0x49:
  156. case 0x4a:
  157. case 0x4b: {
  158. int offset = ByteArray.readU16bit(info, pos);
  159. int index = info[pos + 2] & 0xff;
  160. typeArgumentTarget(pos, type, offset, index);
  161. return pos + 3; }
  162. default:
  163. throw new RuntimeException("invalid target type: " + type);
  164. }
  165. }
  166. void typeParameterTarget(int pos, int targetType, int typeParameterIndex)
  167. throws Exception {}
  168. void supertypeTarget(int pos, int superTypeIndex) throws Exception {}
  169. void typeParameterBoundTarget(int pos, int targetType, int typeParameterIndex,
  170. int boundIndex) throws Exception {}
  171. void emptyTarget(int pos, int targetType) throws Exception {}
  172. void formalParameterTarget(int pos, int formalParameterIndex) throws Exception {}
  173. void throwsTarget(int pos, int throwsTypeIndex) throws Exception {}
  174. int localvarTarget(int pos, int targetType, int tableLength) throws Exception {
  175. for (int i = 0; i < tableLength; i++) {
  176. int start = ByteArray.readU16bit(info, pos);
  177. int length = ByteArray.readU16bit(info, pos + 2);
  178. int index = ByteArray.readU16bit(info, pos + 4);
  179. localvarTarget(pos, targetType, start, length, index);
  180. pos += 6;
  181. }
  182. return pos;
  183. }
  184. void localvarTarget(int pos, int targetType, int startPc, int length, int index)
  185. throws Exception {}
  186. void catchTarget(int pos, int exceptionTableIndex) throws Exception {}
  187. void offsetTarget(int pos, int targetType, int offset) throws Exception {}
  188. void typeArgumentTarget(int pos, int targetType, int offset, int typeArgumentIndex)
  189. throws Exception {}
  190. final int typePath(int pos) throws Exception {
  191. int len = info[pos++] & 0xff;
  192. return typePath(pos, len);
  193. }
  194. int typePath(int pos, int pathLength) throws Exception {
  195. for (int i = 0; i < pathLength; i++) {
  196. int kind = info[pos] & 0xff;
  197. int index = info[pos + 1] & 0xff;
  198. typePath(pos, kind, index);
  199. pos += 2;
  200. }
  201. return pos;
  202. }
  203. void typePath(int pos, int typePathKind, int typeArgumentIndex) throws Exception {}
  204. }
  205. static class Renamer extends AnnotationsAttribute.Renamer {
  206. SubWalker sub;
  207. Renamer(byte[] attrInfo, ConstPool cp, Map map) {
  208. super(attrInfo, cp, map);
  209. sub = new SubWalker(attrInfo);
  210. }
  211. int annotationArray(int pos, int num) throws Exception {
  212. for (int i = 0; i < num; i++) {
  213. int targetType = info[pos] & 0xff;
  214. pos = sub.targetInfo(pos + 1, targetType);
  215. pos = sub.typePath(pos);
  216. pos = annotation(pos);
  217. }
  218. return pos;
  219. }
  220. }
  221. static class Copier extends AnnotationsAttribute.Copier {
  222. SubCopier sub;
  223. Copier(byte[] attrInfo, ConstPool src, ConstPool dest, Map map) {
  224. super(attrInfo, src, dest, map, false);
  225. TypeAnnotationsWriter w = new TypeAnnotationsWriter(output, dest);
  226. writer = w;
  227. sub = new SubCopier(attrInfo, src, dest, map, w);
  228. }
  229. int annotationArray(int pos, int num) throws Exception {
  230. writer.numAnnotations(num);
  231. for (int i = 0; i < num; i++) {
  232. int targetType = info[pos] & 0xff;
  233. pos = sub.targetInfo(pos + 1, targetType);
  234. pos = sub.typePath(pos);
  235. pos = annotation(pos);
  236. }
  237. return pos;
  238. }
  239. }
  240. static class SubCopier extends SubWalker {
  241. ConstPool srcPool, destPool;
  242. Map classnames;
  243. TypeAnnotationsWriter writer;
  244. SubCopier(byte[] attrInfo, ConstPool src, ConstPool dest, Map map,
  245. TypeAnnotationsWriter w)
  246. {
  247. super(attrInfo);
  248. srcPool = src;
  249. destPool = dest;
  250. classnames = map;
  251. writer = w;
  252. }
  253. void typeParameterTarget(int pos, int targetType, int typeParameterIndex)
  254. throws Exception
  255. {
  256. writer.typeParameterTarget(targetType, typeParameterIndex);
  257. }
  258. void supertypeTarget(int pos, int superTypeIndex) throws Exception {
  259. writer.supertypeTarget(superTypeIndex);
  260. }
  261. void typeParameterBoundTarget(int pos, int targetType, int typeParameterIndex,
  262. int boundIndex)
  263. throws Exception
  264. {
  265. writer.typeParameterBoundTarget(targetType, typeParameterIndex, boundIndex);
  266. }
  267. void emptyTarget(int pos, int targetType) throws Exception {
  268. writer.emptyTarget(targetType);
  269. }
  270. void formalParameterTarget(int pos, int formalParameterIndex) throws Exception {
  271. writer.formalParameterTarget(formalParameterIndex);
  272. }
  273. void throwsTarget(int pos, int throwsTypeIndex) throws Exception {
  274. writer.throwsTarget(throwsTypeIndex);
  275. }
  276. int localvarTarget(int pos, int targetType, int tableLength) throws Exception {
  277. writer.localVarTarget(targetType, tableLength);
  278. return super.localvarTarget(pos, targetType, tableLength);
  279. }
  280. void localvarTarget(int pos, int targetType, int startPc, int length, int index)
  281. throws Exception
  282. {
  283. writer.localVarTargetTable(startPc, length, index);
  284. }
  285. void catchTarget(int pos, int exceptionTableIndex) throws Exception {
  286. writer.catchTarget(exceptionTableIndex);
  287. }
  288. void offsetTarget(int pos, int targetType, int offset) throws Exception {
  289. writer.offsetTarget(targetType, offset);
  290. }
  291. void typeArgumentTarget(int pos, int targetType, int offset, int typeArgumentIndex)
  292. throws Exception
  293. {
  294. writer.typeArgumentTarget(targetType, offset, typeArgumentIndex);
  295. }
  296. int typePath(int pos, int pathLength) throws Exception {
  297. writer.typePath(pathLength);
  298. return super.typePath(pos, pathLength);
  299. }
  300. void typePath(int pos, int typePathKind, int typeArgumentIndex) throws Exception {
  301. writer.typePathPath(typePathKind, typeArgumentIndex);
  302. }
  303. }
  304. }