您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

CtMember.java 11KB

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