xref: /aosp_15_r20/external/javassist/src/main/javassist/CtMember.java (revision f1fbf3c2ab775ce834e0af96b7a85bdc7a0eac65)
1*f1fbf3c2SXin Li /*
2*f1fbf3c2SXin Li  * Javassist, a Java-bytecode translator toolkit.
3*f1fbf3c2SXin Li  * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
4*f1fbf3c2SXin Li  *
5*f1fbf3c2SXin Li  * The contents of this file are subject to the Mozilla Public License Version
6*f1fbf3c2SXin Li  * 1.1 (the "License"); you may not use this file except in compliance with
7*f1fbf3c2SXin Li  * the License.  Alternatively, the contents of this file may be used under
8*f1fbf3c2SXin Li  * the terms of the GNU Lesser General Public License Version 2.1 or later,
9*f1fbf3c2SXin Li  * or the Apache License Version 2.0.
10*f1fbf3c2SXin Li  *
11*f1fbf3c2SXin Li  * Software distributed under the License is distributed on an "AS IS" basis,
12*f1fbf3c2SXin Li  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13*f1fbf3c2SXin Li  * for the specific language governing rights and limitations under the
14*f1fbf3c2SXin Li  * License.
15*f1fbf3c2SXin Li  */
16*f1fbf3c2SXin Li 
17*f1fbf3c2SXin Li package javassist;
18*f1fbf3c2SXin Li 
19*f1fbf3c2SXin Li /**
20*f1fbf3c2SXin Li  * An instance of <code>CtMember</code> represents a field, a constructor,
21*f1fbf3c2SXin Li  * or a method.
22*f1fbf3c2SXin Li  */
23*f1fbf3c2SXin Li public abstract class CtMember {
24*f1fbf3c2SXin Li     CtMember next;          // for internal use
25*f1fbf3c2SXin Li     protected CtClass declaringClass;
26*f1fbf3c2SXin Li 
27*f1fbf3c2SXin Li     /* Make a circular link of CtMembers declared in the
28*f1fbf3c2SXin Li      * same class so that they are garbage-collected together
29*f1fbf3c2SXin Li      * at the same time.
30*f1fbf3c2SXin Li      */
31*f1fbf3c2SXin Li     static class Cache extends CtMember {
32*f1fbf3c2SXin Li         @Override
extendToString(StringBuffer buffer)33*f1fbf3c2SXin Li         protected void extendToString(StringBuffer buffer) {}
34*f1fbf3c2SXin Li         @Override
hasAnnotation(String clz)35*f1fbf3c2SXin Li         public boolean hasAnnotation(String clz) { return false; }
36*f1fbf3c2SXin Li         @Override
getAnnotation(Class<?> clz)37*f1fbf3c2SXin Li         public Object getAnnotation(Class<?> clz)
38*f1fbf3c2SXin Li             throws ClassNotFoundException { return null; }
39*f1fbf3c2SXin Li         @Override
getAnnotations()40*f1fbf3c2SXin Li         public Object[] getAnnotations()
41*f1fbf3c2SXin Li             throws ClassNotFoundException { return null; }
42*f1fbf3c2SXin Li         @Override
getAttribute(String name)43*f1fbf3c2SXin Li         public byte[] getAttribute(String name) { return null; }
44*f1fbf3c2SXin Li         @Override
getAvailableAnnotations()45*f1fbf3c2SXin Li         public Object[] getAvailableAnnotations() { return null; }
46*f1fbf3c2SXin Li         @Override
getModifiers()47*f1fbf3c2SXin Li         public int getModifiers() { return 0; }
48*f1fbf3c2SXin Li         @Override
getName()49*f1fbf3c2SXin Li         public String getName() { return null; }
50*f1fbf3c2SXin Li         @Override
getSignature()51*f1fbf3c2SXin Li         public String getSignature() { return null; }
52*f1fbf3c2SXin Li         @Override
setAttribute(String name, byte[] data)53*f1fbf3c2SXin Li         public void setAttribute(String name, byte[] data) {}
54*f1fbf3c2SXin Li         @Override
setModifiers(int mod)55*f1fbf3c2SXin Li         public void setModifiers(int mod) {}
56*f1fbf3c2SXin Li         @Override
getGenericSignature()57*f1fbf3c2SXin Li         public String getGenericSignature() { return null; }
58*f1fbf3c2SXin Li         @Override
setGenericSignature(String sig)59*f1fbf3c2SXin Li         public void setGenericSignature(String sig) {}
60*f1fbf3c2SXin Li 
61*f1fbf3c2SXin Li         private CtMember methodTail;
62*f1fbf3c2SXin Li         private CtMember consTail;     // constructor tail
63*f1fbf3c2SXin Li         private CtMember fieldTail;
64*f1fbf3c2SXin Li 
Cache(CtClassType decl)65*f1fbf3c2SXin Li         Cache(CtClassType decl) {
66*f1fbf3c2SXin Li             super(decl);
67*f1fbf3c2SXin Li             methodTail = this;
68*f1fbf3c2SXin Li             consTail = this;
69*f1fbf3c2SXin Li             fieldTail = this;
70*f1fbf3c2SXin Li             fieldTail.next = this;
71*f1fbf3c2SXin Li         }
72*f1fbf3c2SXin Li 
methodHead()73*f1fbf3c2SXin Li         CtMember methodHead() { return this; }
lastMethod()74*f1fbf3c2SXin Li         CtMember lastMethod() { return methodTail; }
consHead()75*f1fbf3c2SXin Li         CtMember consHead() { return methodTail; }      // may include a static initializer
lastCons()76*f1fbf3c2SXin Li         CtMember lastCons() { return consTail; }
fieldHead()77*f1fbf3c2SXin Li         CtMember fieldHead() { return consTail; }
lastField()78*f1fbf3c2SXin Li         CtMember lastField() { return fieldTail; }
79*f1fbf3c2SXin Li 
addMethod(CtMember method)80*f1fbf3c2SXin Li         void addMethod(CtMember method) {
81*f1fbf3c2SXin Li             method.next = methodTail.next;
82*f1fbf3c2SXin Li             methodTail.next = method;
83*f1fbf3c2SXin Li             if (methodTail == consTail) {
84*f1fbf3c2SXin Li                 consTail = method;
85*f1fbf3c2SXin Li                 if (methodTail == fieldTail)
86*f1fbf3c2SXin Li                     fieldTail = method;
87*f1fbf3c2SXin Li             }
88*f1fbf3c2SXin Li 
89*f1fbf3c2SXin Li             methodTail = method;
90*f1fbf3c2SXin Li         }
91*f1fbf3c2SXin Li 
92*f1fbf3c2SXin Li         /* Both constructors and a class initializer.
93*f1fbf3c2SXin Li          */
addConstructor(CtMember cons)94*f1fbf3c2SXin Li         void addConstructor(CtMember cons) {
95*f1fbf3c2SXin Li             cons.next = consTail.next;
96*f1fbf3c2SXin Li             consTail.next = cons;
97*f1fbf3c2SXin Li             if (consTail == fieldTail)
98*f1fbf3c2SXin Li                 fieldTail = cons;
99*f1fbf3c2SXin Li 
100*f1fbf3c2SXin Li             consTail = cons;
101*f1fbf3c2SXin Li         }
102*f1fbf3c2SXin Li 
addField(CtMember field)103*f1fbf3c2SXin Li         void addField(CtMember field) {
104*f1fbf3c2SXin Li             field.next = this; // or fieldTail.next
105*f1fbf3c2SXin Li             fieldTail.next = field;
106*f1fbf3c2SXin Li             fieldTail = field;
107*f1fbf3c2SXin Li         }
108*f1fbf3c2SXin Li 
count(CtMember head, CtMember tail)109*f1fbf3c2SXin Li         static int count(CtMember head, CtMember tail) {
110*f1fbf3c2SXin Li             int n = 0;
111*f1fbf3c2SXin Li             while (head != tail) {
112*f1fbf3c2SXin Li                 n++;
113*f1fbf3c2SXin Li                 head = head.next;
114*f1fbf3c2SXin Li             }
115*f1fbf3c2SXin Li 
116*f1fbf3c2SXin Li             return n;
117*f1fbf3c2SXin Li         }
118*f1fbf3c2SXin Li 
remove(CtMember mem)119*f1fbf3c2SXin Li         void remove(CtMember mem) {
120*f1fbf3c2SXin Li             CtMember m = this;
121*f1fbf3c2SXin Li             CtMember node;
122*f1fbf3c2SXin Li             while ((node = m.next) != this) {
123*f1fbf3c2SXin Li                 if (node == mem) {
124*f1fbf3c2SXin Li                     m.next = node.next;
125*f1fbf3c2SXin Li                     if (node == methodTail)
126*f1fbf3c2SXin Li                         methodTail = m;
127*f1fbf3c2SXin Li 
128*f1fbf3c2SXin Li                     if (node == consTail)
129*f1fbf3c2SXin Li                         consTail = m;
130*f1fbf3c2SXin Li 
131*f1fbf3c2SXin Li                     if (node == fieldTail)
132*f1fbf3c2SXin Li                         fieldTail = m;
133*f1fbf3c2SXin Li 
134*f1fbf3c2SXin Li                     break;
135*f1fbf3c2SXin Li                 }
136*f1fbf3c2SXin Li                 m = m.next;
137*f1fbf3c2SXin Li             }
138*f1fbf3c2SXin Li         }
139*f1fbf3c2SXin Li     }
140*f1fbf3c2SXin Li 
CtMember(CtClass clazz)141*f1fbf3c2SXin Li     protected CtMember(CtClass clazz) {
142*f1fbf3c2SXin Li         declaringClass = clazz;
143*f1fbf3c2SXin Li         next = null;
144*f1fbf3c2SXin Li     }
145*f1fbf3c2SXin Li 
next()146*f1fbf3c2SXin Li     final CtMember next() { return next; }
147*f1fbf3c2SXin Li 
148*f1fbf3c2SXin Li     /**
149*f1fbf3c2SXin Li      * This method is invoked when setName() or replaceClassName()
150*f1fbf3c2SXin Li      * in CtClass is called.
151*f1fbf3c2SXin Li      *
152*f1fbf3c2SXin Li      * @see CtMethod#nameReplaced()
153*f1fbf3c2SXin Li      */
nameReplaced()154*f1fbf3c2SXin Li     void nameReplaced() {}
155*f1fbf3c2SXin Li 
156*f1fbf3c2SXin Li     @Override
toString()157*f1fbf3c2SXin Li     public String toString() {
158*f1fbf3c2SXin Li         StringBuffer buffer = new StringBuffer(getClass().getName());
159*f1fbf3c2SXin Li         buffer.append("@");
160*f1fbf3c2SXin Li         buffer.append(Integer.toHexString(hashCode()));
161*f1fbf3c2SXin Li         buffer.append("[");
162*f1fbf3c2SXin Li         buffer.append(Modifier.toString(getModifiers()));
163*f1fbf3c2SXin Li         extendToString(buffer);
164*f1fbf3c2SXin Li         buffer.append("]");
165*f1fbf3c2SXin Li         return buffer.toString();
166*f1fbf3c2SXin Li     }
167*f1fbf3c2SXin Li 
168*f1fbf3c2SXin Li     /**
169*f1fbf3c2SXin Li      * Invoked by {@link #toString()} to add to the buffer and provide the
170*f1fbf3c2SXin Li      * complete value.  Subclasses should invoke this method, adding a
171*f1fbf3c2SXin Li      * space before each token.  The modifiers for the member are
172*f1fbf3c2SXin Li      * provided first; subclasses should provide additional data such
173*f1fbf3c2SXin Li      * as return type, field or method name, etc.
174*f1fbf3c2SXin Li      */
extendToString(StringBuffer buffer)175*f1fbf3c2SXin Li     protected abstract void extendToString(StringBuffer buffer);
176*f1fbf3c2SXin Li 
177*f1fbf3c2SXin Li     /**
178*f1fbf3c2SXin Li      * Returns the class that declares this member.
179*f1fbf3c2SXin Li      */
getDeclaringClass()180*f1fbf3c2SXin Li     public CtClass getDeclaringClass() { return declaringClass; }
181*f1fbf3c2SXin Li 
182*f1fbf3c2SXin Li     /**
183*f1fbf3c2SXin Li      * Returns true if this member is accessible from the given class.
184*f1fbf3c2SXin Li      */
visibleFrom(CtClass clazz)185*f1fbf3c2SXin Li     public boolean visibleFrom(CtClass clazz) {
186*f1fbf3c2SXin Li         int mod = getModifiers();
187*f1fbf3c2SXin Li         if (Modifier.isPublic(mod))
188*f1fbf3c2SXin Li             return true;
189*f1fbf3c2SXin Li         else if (Modifier.isPrivate(mod))
190*f1fbf3c2SXin Li             return clazz == declaringClass;
191*f1fbf3c2SXin Li         else {  // package or protected
192*f1fbf3c2SXin Li             String declName = declaringClass.getPackageName();
193*f1fbf3c2SXin Li             String fromName = clazz.getPackageName();
194*f1fbf3c2SXin Li             boolean visible;
195*f1fbf3c2SXin Li             if (declName == null)
196*f1fbf3c2SXin Li                 visible = fromName == null;
197*f1fbf3c2SXin Li             else
198*f1fbf3c2SXin Li                 visible = declName.equals(fromName);
199*f1fbf3c2SXin Li 
200*f1fbf3c2SXin Li             if (!visible && Modifier.isProtected(mod))
201*f1fbf3c2SXin Li                 return clazz.subclassOf(declaringClass);
202*f1fbf3c2SXin Li 
203*f1fbf3c2SXin Li             return visible;
204*f1fbf3c2SXin Li         }
205*f1fbf3c2SXin Li     }
206*f1fbf3c2SXin Li 
207*f1fbf3c2SXin Li     /**
208*f1fbf3c2SXin Li      * Obtains the modifiers of the member.
209*f1fbf3c2SXin Li      *
210*f1fbf3c2SXin Li      * @return          modifiers encoded with
211*f1fbf3c2SXin Li      *                  <code>javassist.Modifier</code>.
212*f1fbf3c2SXin Li      * @see Modifier
213*f1fbf3c2SXin Li      */
getModifiers()214*f1fbf3c2SXin Li     public abstract int getModifiers();
215*f1fbf3c2SXin Li 
216*f1fbf3c2SXin Li     /**
217*f1fbf3c2SXin Li      * Sets the encoded modifiers of the member.
218*f1fbf3c2SXin Li      *
219*f1fbf3c2SXin Li      * @see Modifier
220*f1fbf3c2SXin Li      */
setModifiers(int mod)221*f1fbf3c2SXin Li     public abstract void setModifiers(int mod);
222*f1fbf3c2SXin Li 
223*f1fbf3c2SXin Li     /**
224*f1fbf3c2SXin Li      * Returns true if the class has the specified annotation type.
225*f1fbf3c2SXin Li      *
226*f1fbf3c2SXin Li      * @param clz the annotation type.
227*f1fbf3c2SXin Li      * @return <code>true</code> if the annotation is found, otherwise <code>false</code>.
228*f1fbf3c2SXin Li      * @since 3.11
229*f1fbf3c2SXin Li      */
hasAnnotation(Class<?> clz)230*f1fbf3c2SXin Li     public boolean hasAnnotation(Class<?> clz) {
231*f1fbf3c2SXin Li         return hasAnnotation(clz.getName());
232*f1fbf3c2SXin Li     }
233*f1fbf3c2SXin Li 
234*f1fbf3c2SXin Li     /**
235*f1fbf3c2SXin Li      * Returns true if the class has the specified annotation type.
236*f1fbf3c2SXin Li      *
237*f1fbf3c2SXin Li      * @param annotationTypeName the name of annotation type.
238*f1fbf3c2SXin Li      * @return <code>true</code> if the annotation is found, otherwise <code>false</code>.
239*f1fbf3c2SXin Li      * @since 3.21
240*f1fbf3c2SXin Li      */
hasAnnotation(String annotationTypeName)241*f1fbf3c2SXin Li     public abstract boolean hasAnnotation(String annotationTypeName);
242*f1fbf3c2SXin Li 
243*f1fbf3c2SXin Li     /**
244*f1fbf3c2SXin Li      * Returns the annotation if the class has the specified annotation type.
245*f1fbf3c2SXin Li      * For example, if an annotation <code>@Author</code> is associated
246*f1fbf3c2SXin Li      * with this member, an <code>Author</code> object is returned.
247*f1fbf3c2SXin Li      * The member values can be obtained by calling methods on
248*f1fbf3c2SXin Li      * the <code>Author</code> object.
249*f1fbf3c2SXin Li      *
250*f1fbf3c2SXin Li      * @param annotationType    the annotation type.
251*f1fbf3c2SXin Li      * @return the annotation if found, otherwise <code>null</code>.
252*f1fbf3c2SXin Li      * @since 3.11
253*f1fbf3c2SXin Li      */
getAnnotation(Class<?> annotationType)254*f1fbf3c2SXin Li     public abstract Object getAnnotation(Class<?> annotationType) throws ClassNotFoundException;
255*f1fbf3c2SXin Li 
256*f1fbf3c2SXin Li     /**
257*f1fbf3c2SXin Li      * Returns the annotations associated with this member.
258*f1fbf3c2SXin Li      * For example, if an annotation <code>@Author</code> is associated
259*f1fbf3c2SXin Li      * with this member, the returned array contains an <code>Author</code>
260*f1fbf3c2SXin Li      * object.  The member values can be obtained by calling methods on
261*f1fbf3c2SXin Li      * the <code>Author</code> object.
262*f1fbf3c2SXin Li      *
263*f1fbf3c2SXin Li      * @return an array of annotation-type objects.
264*f1fbf3c2SXin Li      * @see CtClass#getAnnotations()
265*f1fbf3c2SXin Li      */
getAnnotations()266*f1fbf3c2SXin Li     public abstract Object[] getAnnotations() throws ClassNotFoundException;
267*f1fbf3c2SXin Li 
268*f1fbf3c2SXin Li     /**
269*f1fbf3c2SXin Li      * Returns the annotations associated with this member.
270*f1fbf3c2SXin Li      * This method is equivalent to <code>getAnnotations()</code>
271*f1fbf3c2SXin Li      * except that, if any annotations are not on the classpath,
272*f1fbf3c2SXin Li      * they are not included in the returned array.
273*f1fbf3c2SXin Li      *
274*f1fbf3c2SXin Li      * @return an array of annotation-type objects.
275*f1fbf3c2SXin Li      * @see #getAnnotations()
276*f1fbf3c2SXin Li      * @see CtClass#getAvailableAnnotations()
277*f1fbf3c2SXin Li      * @since 3.3
278*f1fbf3c2SXin Li      */
getAvailableAnnotations()279*f1fbf3c2SXin Li     public abstract Object[] getAvailableAnnotations();
280*f1fbf3c2SXin Li 
281*f1fbf3c2SXin Li     /**
282*f1fbf3c2SXin Li      * Obtains the name of the member.
283*f1fbf3c2SXin Li      *
284*f1fbf3c2SXin Li      * <p>As for constructor names, see <code>getName()</code>
285*f1fbf3c2SXin Li      * in <code>CtConstructor</code>.
286*f1fbf3c2SXin Li      *
287*f1fbf3c2SXin Li      * @see CtConstructor#getName()
288*f1fbf3c2SXin Li      */
getName()289*f1fbf3c2SXin Li     public abstract String getName();
290*f1fbf3c2SXin Li 
291*f1fbf3c2SXin Li     /**
292*f1fbf3c2SXin Li      * Returns the character string representing the signature of the member.
293*f1fbf3c2SXin Li      * If two members have the same signature (parameter types etc.),
294*f1fbf3c2SXin Li      * <code>getSignature()</code> returns the same string.
295*f1fbf3c2SXin Li      */
getSignature()296*f1fbf3c2SXin Li     public abstract String getSignature();
297*f1fbf3c2SXin Li 
298*f1fbf3c2SXin Li     /**
299*f1fbf3c2SXin Li      * Returns the generic signature of the member.
300*f1fbf3c2SXin Li      *
301*f1fbf3c2SXin Li      * @see javassist.bytecode.SignatureAttribute#toFieldSignature(String)
302*f1fbf3c2SXin Li      * @see javassist.bytecode.SignatureAttribute#toMethodSignature(String)
303*f1fbf3c2SXin Li      * @see CtClass#getGenericSignature()
304*f1fbf3c2SXin Li      * @since 3.17
305*f1fbf3c2SXin Li      */
getGenericSignature()306*f1fbf3c2SXin Li     public abstract String getGenericSignature();
307*f1fbf3c2SXin Li 
308*f1fbf3c2SXin Li     /**
309*f1fbf3c2SXin Li      * Sets the generic signature of the member.
310*f1fbf3c2SXin Li      *
311*f1fbf3c2SXin Li      * @param sig   a new generic signature.
312*f1fbf3c2SXin Li      * @see javassist.bytecode.SignatureAttribute.ObjectType#encode()
313*f1fbf3c2SXin Li      * @see javassist.bytecode.SignatureAttribute.MethodSignature#encode()
314*f1fbf3c2SXin Li      * @see CtClass#setGenericSignature(String)
315*f1fbf3c2SXin Li      * @since 3.17
316*f1fbf3c2SXin Li      */
setGenericSignature(String sig)317*f1fbf3c2SXin Li     public abstract void setGenericSignature(String sig);
318*f1fbf3c2SXin Li 
319*f1fbf3c2SXin Li     /**
320*f1fbf3c2SXin Li      * Obtains a user-defined attribute with the given name.
321*f1fbf3c2SXin Li      * If that attribute is not found in the class file, this
322*f1fbf3c2SXin Li      * method returns null.
323*f1fbf3c2SXin Li      *
324*f1fbf3c2SXin Li      * <p>Note that an attribute is a data block specified by
325*f1fbf3c2SXin Li      * the class file format.
326*f1fbf3c2SXin Li      * See {@link javassist.bytecode.AttributeInfo}.
327*f1fbf3c2SXin Li      *
328*f1fbf3c2SXin Li      * @param name              attribute name
329*f1fbf3c2SXin Li      */
getAttribute(String name)330*f1fbf3c2SXin Li     public abstract byte[] getAttribute(String name);
331*f1fbf3c2SXin Li 
332*f1fbf3c2SXin Li     /**
333*f1fbf3c2SXin Li      * Adds a user-defined attribute. The attribute is saved in the class file.
334*f1fbf3c2SXin Li      *
335*f1fbf3c2SXin Li      * <p>Note that an attribute is a data block specified by
336*f1fbf3c2SXin Li      * the class file format.
337*f1fbf3c2SXin Li      * See {@link javassist.bytecode.AttributeInfo}.
338*f1fbf3c2SXin Li      *
339*f1fbf3c2SXin Li      * @param name      attribute name
340*f1fbf3c2SXin Li      * @param data      attribute value
341*f1fbf3c2SXin Li      */
setAttribute(String name, byte[] data)342*f1fbf3c2SXin Li     public abstract void setAttribute(String name, byte[] data);
343*f1fbf3c2SXin Li }
344