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.

FieldInfo.java 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * Javassist, a Java-bytecode translator toolkit.
  3. * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. Alternatively, the contents of this file may be used under
  8. * the terms of the GNU Lesser General Public License Version 2.1 or later,
  9. * or the Apache License Version 2.0.
  10. *
  11. * Software distributed under the License is distributed on an "AS IS" basis,
  12. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13. * for the specific language governing rights and limitations under the
  14. * License.
  15. */
  16. package javassist.bytecode;
  17. import java.io.DataInputStream;
  18. import java.io.DataOutputStream;
  19. import java.io.IOException;
  20. import java.util.List;
  21. import java.util.ArrayList;
  22. /**
  23. * <code>field_info</code> structure.
  24. *
  25. * <p>The following code adds a public field <code>width</code>
  26. * of <code>int</code> type:
  27. * <blockquote><pre>
  28. * ClassFile cf = ...
  29. * FieldInfo f = new FieldInfo(cf.getConstPool(), "width", "I");
  30. * f.setAccessFlags(AccessFlag.PUBLIC);
  31. * cf.addField(f);
  32. * </pre></blockquote>
  33. *
  34. * @see javassist.CtField#getFieldInfo()
  35. */
  36. public final class FieldInfo {
  37. ConstPool constPool;
  38. int accessFlags;
  39. int name;
  40. String cachedName;
  41. String cachedType;
  42. int descriptor;
  43. ArrayList attribute; // may be null.
  44. private FieldInfo(ConstPool cp) {
  45. constPool = cp;
  46. accessFlags = 0;
  47. attribute = null;
  48. }
  49. /**
  50. * Constructs a <code>field_info</code> structure.
  51. *
  52. * @param cp a constant pool table
  53. * @param fieldName field name
  54. * @param desc field descriptor
  55. *
  56. * @see Descriptor
  57. */
  58. public FieldInfo(ConstPool cp, String fieldName, String desc) {
  59. this(cp);
  60. name = cp.addUtf8Info(fieldName);
  61. cachedName = fieldName;
  62. descriptor = cp.addUtf8Info(desc);
  63. }
  64. FieldInfo(ConstPool cp, DataInputStream in) throws IOException {
  65. this(cp);
  66. read(in);
  67. }
  68. /**
  69. * Returns a string representation of the object.
  70. */
  71. public String toString() {
  72. return getName() + " " + getDescriptor();
  73. }
  74. /**
  75. * Copies all constant pool items to a given new constant pool
  76. * and replaces the original items with the new ones.
  77. * This is used for garbage collecting the items of removed fields
  78. * and methods.
  79. *
  80. * @param cp the destination
  81. */
  82. void compact(ConstPool cp) {
  83. name = cp.addUtf8Info(getName());
  84. descriptor = cp.addUtf8Info(getDescriptor());
  85. attribute = AttributeInfo.copyAll(attribute, cp);
  86. constPool = cp;
  87. }
  88. void prune(ConstPool cp) {
  89. ArrayList newAttributes = new ArrayList();
  90. AttributeInfo invisibleAnnotations
  91. = getAttribute(AnnotationsAttribute.invisibleTag);
  92. if (invisibleAnnotations != null) {
  93. invisibleAnnotations = invisibleAnnotations.copy(cp, null);
  94. newAttributes.add(invisibleAnnotations);
  95. }
  96. AttributeInfo visibleAnnotations
  97. = getAttribute(AnnotationsAttribute.visibleTag);
  98. if (visibleAnnotations != null) {
  99. visibleAnnotations = visibleAnnotations.copy(cp, null);
  100. newAttributes.add(visibleAnnotations);
  101. }
  102. AttributeInfo signature
  103. = getAttribute(SignatureAttribute.tag);
  104. if (signature != null) {
  105. signature = signature.copy(cp, null);
  106. newAttributes.add(signature);
  107. }
  108. int index = getConstantValue();
  109. if (index != 0) {
  110. index = constPool.copy(index, cp, null);
  111. newAttributes.add(new ConstantAttribute(cp, index));
  112. }
  113. attribute = newAttributes;
  114. name = cp.addUtf8Info(getName());
  115. descriptor = cp.addUtf8Info(getDescriptor());
  116. constPool = cp;
  117. }
  118. /**
  119. * Returns the constant pool table used
  120. * by this <code>field_info</code>.
  121. */
  122. public ConstPool getConstPool() {
  123. return constPool;
  124. }
  125. /**
  126. * Returns the field name.
  127. */
  128. public String getName() {
  129. if (cachedName == null)
  130. cachedName = constPool.getUtf8Info(name);
  131. return cachedName;
  132. }
  133. /**
  134. * Sets the field name.
  135. */
  136. public void setName(String newName) {
  137. name = constPool.addUtf8Info(newName);
  138. cachedName = newName;
  139. }
  140. /**
  141. * Returns the access flags.
  142. *
  143. * @see AccessFlag
  144. */
  145. public int getAccessFlags() {
  146. return accessFlags;
  147. }
  148. /**
  149. * Sets the access flags.
  150. *
  151. * @see AccessFlag
  152. */
  153. public void setAccessFlags(int acc) {
  154. accessFlags = acc;
  155. }
  156. /**
  157. * Returns the field descriptor.
  158. *
  159. * @see Descriptor
  160. */
  161. public String getDescriptor() {
  162. return constPool.getUtf8Info(descriptor);
  163. }
  164. /**
  165. * Sets the field descriptor.
  166. *
  167. * @see Descriptor
  168. */
  169. public void setDescriptor(String desc) {
  170. if (!desc.equals(getDescriptor()))
  171. descriptor = constPool.addUtf8Info(desc);
  172. }
  173. /**
  174. * Finds a ConstantValue attribute and returns the index into
  175. * the <code>constant_pool</code> table.
  176. *
  177. * @return 0 if a ConstantValue attribute is not found.
  178. */
  179. public int getConstantValue() {
  180. if ((accessFlags & AccessFlag.STATIC) == 0)
  181. return 0;
  182. ConstantAttribute attr
  183. = (ConstantAttribute)getAttribute(ConstantAttribute.tag);
  184. if (attr == null)
  185. return 0;
  186. else
  187. return attr.getConstantValue();
  188. }
  189. /**
  190. * Returns all the attributes. The returned <code>List</code> object
  191. * is shared with this object. If you add a new attribute to the list,
  192. * the attribute is also added to the field represented by this
  193. * object. If you remove an attribute from the list, it is also removed
  194. * from the field.
  195. *
  196. * @return a list of <code>AttributeInfo</code> objects.
  197. * @see AttributeInfo
  198. */
  199. public List getAttributes() {
  200. if (attribute == null)
  201. attribute = new ArrayList();
  202. return attribute;
  203. }
  204. /**
  205. * Returns the attribute with the specified name.
  206. * It returns null if the specified attribute is not found.
  207. *
  208. * @param name attribute name
  209. * @see #getAttributes()
  210. */
  211. public AttributeInfo getAttribute(String name) {
  212. return AttributeInfo.lookup(attribute, name);
  213. }
  214. /**
  215. * Appends an attribute. If there is already an attribute with
  216. * the same name, the new one substitutes for it.
  217. *
  218. * @see #getAttributes()
  219. */
  220. public void addAttribute(AttributeInfo info) {
  221. if (attribute == null)
  222. attribute = new ArrayList();
  223. AttributeInfo.remove(attribute, info.getName());
  224. attribute.add(info);
  225. }
  226. private void read(DataInputStream in) throws IOException {
  227. accessFlags = in.readUnsignedShort();
  228. name = in.readUnsignedShort();
  229. descriptor = in.readUnsignedShort();
  230. int n = in.readUnsignedShort();
  231. attribute = new ArrayList();
  232. for (int i = 0; i < n; ++i)
  233. attribute.add(AttributeInfo.read(constPool, in));
  234. }
  235. void write(DataOutputStream out) throws IOException {
  236. out.writeShort(accessFlags);
  237. out.writeShort(name);
  238. out.writeShort(descriptor);
  239. if (attribute == null)
  240. out.writeShort(0);
  241. else {
  242. out.writeShort(attribute.size());
  243. AttributeInfo.writeAll(attribute, out);
  244. }
  245. }
  246. }