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