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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  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. @Override
  54. public AttributeInfo copy(ConstPool newCp, Map<String,String> classnames) {
  55. Copier copier = new Copier(info, constPool, newCp, classnames);
  56. try {
  57. copier.annotationArray();
  58. return new TypeAnnotationsAttribute(newCp, getName(), copier.close());
  59. }
  60. catch (Exception e) {
  61. throw new RuntimeException(e);
  62. }
  63. }
  64. /**
  65. * @param oldname a JVM class name.
  66. * @param newname a JVM class name.
  67. */
  68. @Override
  69. void renameClass(String oldname, String newname) {
  70. Map<String,String> map = new HashMap<String,String>();
  71. map.put(oldname, newname);
  72. renameClass(map);
  73. }
  74. @Override
  75. void renameClass(Map<String,String> classnames) {
  76. Renamer renamer = new Renamer(info, getConstPool(), classnames);
  77. try {
  78. renamer.annotationArray();
  79. } catch (Exception e) {
  80. throw new RuntimeException(e);
  81. }
  82. }
  83. @Override
  84. void getRefClasses(Map<String,String> classnames) { renameClass(classnames); }
  85. /**
  86. * To visit each elements of the type annotation attribute,
  87. * call {@code annotationArray()}.
  88. *
  89. * @see #annotationArray()
  90. */
  91. static class TAWalker extends AnnotationsAttribute.Walker {
  92. SubWalker subWalker;
  93. TAWalker(byte[] attrInfo) {
  94. super(attrInfo);
  95. subWalker = new SubWalker(attrInfo);
  96. }
  97. @Override
  98. int annotationArray(int pos, int num) throws Exception {
  99. for (int i = 0; i < num; i++) {
  100. int targetType = info[pos] & 0xff;
  101. pos = subWalker.targetInfo(pos + 1, targetType);
  102. pos = subWalker.typePath(pos);
  103. pos = annotation(pos);
  104. }
  105. return pos;
  106. }
  107. }
  108. static class SubWalker {
  109. byte[] info;
  110. SubWalker(byte[] attrInfo) {
  111. info = attrInfo;
  112. }
  113. final int targetInfo(int pos, int type) throws Exception {
  114. switch (type) {
  115. case 0x00:
  116. case 0x01: {
  117. int index = info[pos] & 0xff;
  118. typeParameterTarget(pos, type, index);
  119. return pos + 1; }
  120. case 0x10: {
  121. int index = ByteArray.readU16bit(info, pos);
  122. supertypeTarget(pos, index);
  123. return pos + 2; }
  124. case 0x11:
  125. case 0x12: {
  126. int param = info[pos] & 0xff;
  127. int bound = info[pos + 1] & 0xff;
  128. typeParameterBoundTarget(pos, type, param, bound);
  129. return pos + 2; }
  130. case 0x13:
  131. case 0x14:
  132. case 0x15:
  133. emptyTarget(pos, type);
  134. return pos;
  135. case 0x16: {
  136. int index = info[pos] & 0xff;
  137. formalParameterTarget(pos, index);
  138. return pos + 1; }
  139. case 0x17: {
  140. int index = ByteArray.readU16bit(info, pos);
  141. throwsTarget(pos, index);
  142. return pos + 2; }
  143. case 0x40:
  144. case 0x41: {
  145. int len = ByteArray.readU16bit(info, pos);
  146. return localvarTarget(pos + 2, type, len); }
  147. case 0x42: {
  148. int index = ByteArray.readU16bit(info, pos);
  149. catchTarget(pos, index);
  150. return pos + 2; }
  151. case 0x43:
  152. case 0x44:
  153. case 0x45:
  154. case 0x46: {
  155. int offset = ByteArray.readU16bit(info, pos);
  156. offsetTarget(pos, type, offset);
  157. return pos + 2; }
  158. case 0x47:
  159. case 0x48:
  160. case 0x49:
  161. case 0x4a:
  162. case 0x4b: {
  163. int offset = ByteArray.readU16bit(info, pos);
  164. int index = info[pos + 2] & 0xff;
  165. typeArgumentTarget(pos, type, offset, index);
  166. return pos + 3; }
  167. default:
  168. throw new RuntimeException("invalid target type: " + type);
  169. }
  170. }
  171. void typeParameterTarget(int pos, int targetType, int typeParameterIndex)
  172. throws Exception {}
  173. void supertypeTarget(int pos, int superTypeIndex) throws Exception {}
  174. void typeParameterBoundTarget(int pos, int targetType, int typeParameterIndex,
  175. int boundIndex) throws Exception {}
  176. void emptyTarget(int pos, int targetType) throws Exception {}
  177. void formalParameterTarget(int pos, int formalParameterIndex) throws Exception {}
  178. void throwsTarget(int pos, int throwsTypeIndex) throws Exception {}
  179. int localvarTarget(int pos, int targetType, int tableLength) throws Exception {
  180. for (int i = 0; i < tableLength; i++) {
  181. int start = ByteArray.readU16bit(info, pos);
  182. int length = ByteArray.readU16bit(info, pos + 2);
  183. int index = ByteArray.readU16bit(info, pos + 4);
  184. localvarTarget(pos, targetType, start, length, index);
  185. pos += 6;
  186. }
  187. return pos;
  188. }
  189. void localvarTarget(int pos, int targetType, int startPc, int length, int index)
  190. throws Exception {}
  191. void catchTarget(int pos, int exceptionTableIndex) throws Exception {}
  192. void offsetTarget(int pos, int targetType, int offset) throws Exception {}
  193. void typeArgumentTarget(int pos, int targetType, int offset, int typeArgumentIndex)
  194. throws Exception {}
  195. final int typePath(int pos) throws Exception {
  196. int len = info[pos++] & 0xff;
  197. return typePath(pos, len);
  198. }
  199. int typePath(int pos, int pathLength) throws Exception {
  200. for (int i = 0; i < pathLength; i++) {
  201. int kind = info[pos] & 0xff;
  202. int index = info[pos + 1] & 0xff;
  203. typePath(pos, kind, index);
  204. pos += 2;
  205. }
  206. return pos;
  207. }
  208. void typePath(int pos, int typePathKind, int typeArgumentIndex) throws Exception {}
  209. }
  210. static class Renamer extends AnnotationsAttribute.Renamer {
  211. SubWalker sub;
  212. Renamer(byte[] attrInfo, ConstPool cp, Map<String,String> map) {
  213. super(attrInfo, cp, map);
  214. sub = new SubWalker(attrInfo);
  215. }
  216. @Override
  217. int annotationArray(int pos, int num) throws Exception {
  218. for (int i = 0; i < num; i++) {
  219. int targetType = info[pos] & 0xff;
  220. pos = sub.targetInfo(pos + 1, targetType);
  221. pos = sub.typePath(pos);
  222. pos = annotation(pos);
  223. }
  224. return pos;
  225. }
  226. }
  227. static class Copier extends AnnotationsAttribute.Copier {
  228. SubCopier sub;
  229. Copier(byte[] attrInfo, ConstPool src, ConstPool dest, Map<String,String> map) {
  230. super(attrInfo, src, dest, map, false);
  231. TypeAnnotationsWriter w = new TypeAnnotationsWriter(output, dest);
  232. writer = w;
  233. sub = new SubCopier(attrInfo, src, dest, map, w);
  234. }
  235. @Override
  236. int annotationArray(int pos, int num) throws Exception {
  237. writer.numAnnotations(num);
  238. for (int i = 0; i < num; i++) {
  239. int targetType = info[pos] & 0xff;
  240. pos = sub.targetInfo(pos + 1, targetType);
  241. pos = sub.typePath(pos);
  242. pos = annotation(pos);
  243. }
  244. return pos;
  245. }
  246. }
  247. static class SubCopier extends SubWalker {
  248. ConstPool srcPool, destPool;
  249. Map<String,String> classnames;
  250. TypeAnnotationsWriter writer;
  251. SubCopier(byte[] attrInfo, ConstPool src, ConstPool dest,
  252. Map<String,String> map, TypeAnnotationsWriter w)
  253. {
  254. super(attrInfo);
  255. srcPool = src;
  256. destPool = dest;
  257. classnames = map;
  258. writer = w;
  259. }
  260. @Override
  261. void typeParameterTarget(int pos, int targetType, int typeParameterIndex)
  262. throws Exception
  263. {
  264. writer.typeParameterTarget(targetType, typeParameterIndex);
  265. }
  266. @Override
  267. void supertypeTarget(int pos, int superTypeIndex) throws Exception {
  268. writer.supertypeTarget(superTypeIndex);
  269. }
  270. @Override
  271. void typeParameterBoundTarget(int pos, int targetType, int typeParameterIndex,
  272. int boundIndex)
  273. throws Exception
  274. {
  275. writer.typeParameterBoundTarget(targetType, typeParameterIndex, boundIndex);
  276. }
  277. @Override
  278. void emptyTarget(int pos, int targetType) throws Exception {
  279. writer.emptyTarget(targetType);
  280. }
  281. @Override
  282. void formalParameterTarget(int pos, int formalParameterIndex) throws Exception {
  283. writer.formalParameterTarget(formalParameterIndex);
  284. }
  285. @Override
  286. void throwsTarget(int pos, int throwsTypeIndex) throws Exception {
  287. writer.throwsTarget(throwsTypeIndex);
  288. }
  289. @Override
  290. int localvarTarget(int pos, int targetType, int tableLength) throws Exception {
  291. writer.localVarTarget(targetType, tableLength);
  292. return super.localvarTarget(pos, targetType, tableLength);
  293. }
  294. @Override
  295. void localvarTarget(int pos, int targetType, int startPc, int length, int index)
  296. throws Exception
  297. {
  298. writer.localVarTargetTable(startPc, length, index);
  299. }
  300. @Override
  301. void catchTarget(int pos, int exceptionTableIndex) throws Exception {
  302. writer.catchTarget(exceptionTableIndex);
  303. }
  304. @Override
  305. void offsetTarget(int pos, int targetType, int offset) throws Exception {
  306. writer.offsetTarget(targetType, offset);
  307. }
  308. @Override
  309. void typeArgumentTarget(int pos, int targetType, int offset, int typeArgumentIndex)
  310. throws Exception
  311. {
  312. writer.typeArgumentTarget(targetType, offset, typeArgumentIndex);
  313. }
  314. @Override
  315. int typePath(int pos, int pathLength) throws Exception {
  316. writer.typePath(pathLength);
  317. return super.typePath(pos, pathLength);
  318. }
  319. @Override
  320. void typePath(int pos, int typePathKind, int typeArgumentIndex) throws Exception {
  321. writer.typePathPath(typePathKind, typeArgumentIndex);
  322. }
  323. }
  324. }