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.

CtMember.java 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  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;
  17. /**
  18. * An instance of <code>CtMember</code> represents a field, a constructor,
  19. * or a method.
  20. */
  21. public abstract class CtMember {
  22. CtMember next; // for internal use
  23. protected CtClass declaringClass;
  24. /* Make a circular link of CtMembers declared in the
  25. * same class so that they are garbage-collected together
  26. * at the same time.
  27. */
  28. static class Cache extends CtMember {
  29. protected void extendToString(StringBuffer buffer) {}
  30. public boolean hasAnnotation(Class clz) { return false; }
  31. public Object getAnnotation(Class clz)
  32. throws ClassNotFoundException { return null; }
  33. public Object[] getAnnotations()
  34. throws ClassNotFoundException { return null; }
  35. public byte[] getAttribute(String name) { return null; }
  36. public Object[] getAvailableAnnotations() { return null; }
  37. public int getModifiers() { return 0; }
  38. public String getName() { return null; }
  39. public String getSignature() { return null; }
  40. public void setAttribute(String name, byte[] data) {}
  41. public void setModifiers(int mod) {}
  42. public String getGenericSignature() { return null; }
  43. public void setGenericSignature(String sig) {}
  44. private CtMember methodTail;
  45. private CtMember consTail; // constructor tail
  46. private CtMember fieldTail;
  47. Cache(CtClassType decl) {
  48. super(decl);
  49. methodTail = this;
  50. consTail = this;
  51. fieldTail = this;
  52. fieldTail.next = this;
  53. }
  54. CtMember methodHead() { return this; }
  55. CtMember lastMethod() { return methodTail; }
  56. CtMember consHead() { return methodTail; } // may include a static initializer
  57. CtMember lastCons() { return consTail; }
  58. CtMember fieldHead() { return consTail; }
  59. CtMember lastField() { return fieldTail; }
  60. void addMethod(CtMember method) {
  61. method.next = methodTail.next;
  62. methodTail.next = method;
  63. if (methodTail == consTail) {
  64. consTail = method;
  65. if (methodTail == fieldTail)
  66. fieldTail = method;
  67. }
  68. methodTail = method;
  69. }
  70. /* Both constructors and a class initializer.
  71. */
  72. void addConstructor(CtMember cons) {
  73. cons.next = consTail.next;
  74. consTail.next = cons;
  75. if (consTail == fieldTail)
  76. fieldTail = cons;
  77. consTail = cons;
  78. }
  79. void addField(CtMember field) {
  80. field.next = this; // or fieldTail.next
  81. fieldTail.next = field;
  82. fieldTail = field;
  83. }
  84. static int count(CtMember head, CtMember tail) {
  85. int n = 0;
  86. while (head != tail) {
  87. n++;
  88. head = head.next;
  89. }
  90. return n;
  91. }
  92. void remove(CtMember mem) {
  93. CtMember m = this;
  94. CtMember node;
  95. while ((node = m.next) != this) {
  96. if (node == mem) {
  97. m.next = node.next;
  98. if (node == methodTail)
  99. methodTail = m;
  100. if (node == consTail)
  101. consTail = m;
  102. if (node == fieldTail)
  103. fieldTail = m;
  104. break;
  105. }
  106. else
  107. m = m.next;
  108. }
  109. }
  110. }
  111. protected CtMember(CtClass clazz) {
  112. declaringClass = clazz;
  113. next = null;
  114. }
  115. final CtMember next() { return next; }
  116. /**
  117. * This method is invoked when setName() or replaceClassName()
  118. * in CtClass is called.
  119. *
  120. * @see CtMethod#nameReplaced()
  121. */
  122. void nameReplaced() {}
  123. public String toString() {
  124. StringBuffer buffer = new StringBuffer(getClass().getName());
  125. buffer.append("@");
  126. buffer.append(Integer.toHexString(hashCode()));
  127. buffer.append("[");
  128. buffer.append(Modifier.toString(getModifiers()));
  129. extendToString(buffer);
  130. buffer.append("]");
  131. return buffer.toString();
  132. }
  133. /**
  134. * Invoked by {@link #toString()} to add to the buffer and provide the
  135. * complete value. Subclasses should invoke this method, adding a
  136. * space before each token. The modifiers for the member are
  137. * provided first; subclasses should provide additional data such
  138. * as return type, field or method name, etc.
  139. */
  140. protected abstract void extendToString(StringBuffer buffer);
  141. /**
  142. * Returns the class that declares this member.
  143. */
  144. public CtClass getDeclaringClass() { return declaringClass; }
  145. /**
  146. * Returns true if this member is accessible from the given class.
  147. */
  148. public boolean visibleFrom(CtClass clazz) {
  149. int mod = getModifiers();
  150. if (Modifier.isPublic(mod))
  151. return true;
  152. else if (Modifier.isPrivate(mod))
  153. return clazz == declaringClass;
  154. else { // package or protected
  155. String declName = declaringClass.getPackageName();
  156. String fromName = clazz.getPackageName();
  157. boolean visible;
  158. if (declName == null)
  159. visible = fromName == null;
  160. else
  161. visible = declName.equals(fromName);
  162. if (!visible && Modifier.isProtected(mod))
  163. return clazz.subclassOf(declaringClass);
  164. return visible;
  165. }
  166. }
  167. /**
  168. * Obtains the modifiers of the member.
  169. *
  170. * @return modifiers encoded with
  171. * <code>javassist.Modifier</code>.
  172. * @see Modifier
  173. */
  174. public abstract int getModifiers();
  175. /**
  176. * Sets the encoded modifiers of the member.
  177. *
  178. * @see Modifier
  179. */
  180. public abstract void setModifiers(int mod);
  181. /**
  182. * Returns true if the class has the specified annotation class.
  183. *
  184. * @param clz the annotation class.
  185. * @return <code>true</code> if the annotation is found, otherwise <code>false</code>.
  186. * @since 3.11
  187. */
  188. public abstract boolean hasAnnotation(Class clz);
  189. /**
  190. * Returns the annotation if the class has the specified annotation class.
  191. * For example, if an annotation <code>@Author</code> is associated
  192. * with this member, an <code>Author</code> object is returned.
  193. * The member values can be obtained by calling methods on
  194. * the <code>Author</code> object.
  195. *
  196. * @param clz the annotation class.
  197. * @return the annotation if found, otherwise <code>null</code>.
  198. * @since 3.11
  199. */
  200. public abstract Object getAnnotation(Class clz) throws ClassNotFoundException;
  201. /**
  202. * Returns the annotations associated with this member.
  203. * For example, if an annotation <code>@Author</code> is associated
  204. * with this member, the returned array contains an <code>Author</code>
  205. * object. The member values can be obtained by calling methods on
  206. * the <code>Author</code> object.
  207. *
  208. * @return an array of annotation-type objects.
  209. * @see CtClass#getAnnotations()
  210. */
  211. public abstract Object[] getAnnotations() throws ClassNotFoundException;
  212. /**
  213. * Returns the annotations associated with this member.
  214. * This method is equivalent to <code>getAnnotations()</code>
  215. * except that, if any annotations are not on the classpath,
  216. * they are not included in the returned array.
  217. *
  218. * @return an array of annotation-type objects.
  219. * @see #getAnnotations()
  220. * @see CtClass#getAvailableAnnotations()
  221. * @since 3.3
  222. */
  223. public abstract Object[] getAvailableAnnotations();
  224. /**
  225. * Obtains the name of the member.
  226. *
  227. * <p>As for constructor names, see <code>getName()</code>
  228. * in <code>CtConstructor</code>.
  229. *
  230. * @see CtConstructor#getName()
  231. */
  232. public abstract String getName();
  233. /**
  234. * Returns the character string representing the signature of the member.
  235. * If two members have the same signature (parameter types etc.),
  236. * <code>getSignature()</code> returns the same string.
  237. */
  238. public abstract String getSignature();
  239. /**
  240. * Returns the generic signature of the member.
  241. *
  242. * @see javassist.bytecode.SignatureAttribute#toFieldSignature(String)
  243. * @see javassist.bytecode.SignatureAttribute#toMethodSignature(String)
  244. * @see CtClass#getGenericSignature()
  245. * @since 3.17
  246. */
  247. public abstract String getGenericSignature();
  248. /**
  249. * Sets the generic signature of the member.
  250. *
  251. * @param sig a new generic signature.
  252. * @see javassist.bytecode.SignatureAttribute.ObjectType#encode()
  253. * @see javassist.bytecode.SignatureAttribute.MethodSignature#encode()
  254. * @see CtClass#setGenericSignature(String)
  255. * @since 3.17
  256. */
  257. public abstract void setGenericSignature(String sig);
  258. /**
  259. * Obtains a user-defined attribute with the given name.
  260. * If that attribute is not found in the class file, this
  261. * method returns null.
  262. *
  263. * <p>Note that an attribute is a data block specified by
  264. * the class file format.
  265. * See {@link javassist.bytecode.AttributeInfo}.
  266. *
  267. * @param name attribute name
  268. */
  269. public abstract byte[] getAttribute(String name);
  270. /**
  271. * Adds a user-defined attribute. The attribute is saved in the class file.
  272. *
  273. * <p>Note that an attribute is a data block specified by
  274. * the class file format.
  275. * See {@link javassist.bytecode.AttributeInfo}.
  276. *
  277. * @param name attribute name
  278. * @param data attribute value
  279. */
  280. public abstract void setAttribute(String name, byte[] data);
  281. }