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 9.5KB

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