📄 classtype.java
字号:
// Copyright (c) 1997, 1998, 1999, 2001, 2002, 2004 Per M.A. Bothner.// This is free software; for terms and warranty disclaimer see ./COPYING.package gnu.bytecodecvssnap;import java.io.*;import java.util.Vector;public class ClassType extends ObjectType implements AttrContainer, Externalizable{ public static final int minor_version = 3; public static final int major_version = 45; /** Find a ClassType with the given name, or create a new one. * Use this for "library classes", where you need the field/method types, * but not one where you are about to generate code for. * @param name the name of the class (e..g. "java.lang.String"). */ public static ClassType make(String name) { return (ClassType) Type.getType(name); } public static ClassType make (String name, ClassType superClass) { ClassType type = make(name); if (type.superClass == null) type.setSuper(superClass); return type; } int thisClassIndex; /** The super (base) class of the current class. * X.superClass == null means the superClass has not been specified, * and defaults to java.lang.Object. */ ClassType superClass; /** The constant pool index of the superClass, or -1 if unassigned. */ int superClassIndex = -1; ClassType[] interfaces; int[] interfaceIndexes; public int access_flags; Attribute attributes; public final Attribute getAttributes () { return attributes; } public final void setAttributes (Attribute attributes) { this.attributes = attributes; } public static final ClassType[] noClasses = { }; boolean emitDebugInfo = true; ConstantPool constants; public final ConstantPool getConstants () { return constants; } public final CpoolEntry getConstant(int i) { if (constants == null || constants.pool == null || i > constants.count) return null; return constants.pool[i]; } /** Return the modifiers (access flags) for this class. */ public final int getModifiers() { if (access_flags == 0 && (flags & EXISTING_CLASS) != 0 && getReflectClass() != null) access_flags = reflectClass.getModifiers(); return access_flags; } /** Set the modifiers (access flags) for this class. */ public final void setModifiers(int flags) { access_flags = flags; } /** Check if a component is accessible from this class. * @param declaring the class containing the component (a field, method, * or inner class) * @param modifiers the access flags of the component * @return true if the specified component can be accessed from this class. */ public boolean isAccessible (ClassType declaring, int modifiers) { int cmods = declaring.getModifiers(); if ((modifiers & Access.PUBLIC) != 0 && (cmods & Access.PUBLIC) != 0) return true; String callerName = getName(); String className = declaring.getName(); if (callerName.equals(className)) return true; if ((modifiers & Access.PRIVATE) != 0) return false; int dot = callerName.lastIndexOf('.'); String callerPackage = dot >= 0 ? callerName.substring(0, dot) : ""; dot = className.lastIndexOf('.'); String classPackage = dot >= 0 ? className.substring(0, dot) : ""; if (callerPackage.equals(classPackage)) return true; if ((modifiers & Access.PROTECTED) != 0 && declaring.isSubclass(this)) return true; return false; } /** Sets the name of the class being defined in this classfile. * @param name the name to give to the class */ public void setName (String name) { this_name = name; setSignature("L"+name.replace('.', '/')+";"); } SourceDebugExtAttr sourceDbgExt; /** Create a <code>SourceDebugExtAttr</code>, if needed, and * set the "stratum". The stratum is typically a programming language * such as "JSP", "Scheme", or "Java" (the default). */ public void setStratum (String stratum) { if (sourceDbgExt == null) sourceDbgExt = new SourceDebugExtAttr(this); sourceDbgExt.addStratum(stratum); } /** Set the name of the SourceFile associated with this class. */ public void setSourceFile (String name) { if (sourceDbgExt != null) { sourceDbgExt.addFile(name); if (sourceDbgExt.fileCount > 1) return; } name = SourceFileAttr.fixSourceFile(name); int slash = name.lastIndexOf('/'); if (slash >= 0) name = name.substring(slash+1); SourceFileAttr.setSourceFile(this, name); } /** * Set the superclass of the is class. * @param name name of super class, or null if this is "Object". */ public void setSuper (String name) { setSuper(name == null ? Type.pointer_type : ClassType.make(name)); } public void setSuper (ClassType superClass) { this.superClass = superClass; } public ClassType getSuperclass () { if (superClass == null && ! isInterface() && ! ("java.lang.Object".equals(getName())) && getReflectClass() != null) { superClass = (ClassType) make(reflectClass.getSuperclass()); } return superClass; } public String getPackageName() { String name = getName(); int index = name.lastIndexOf('.'); return index < 0 ? name : name.substring(0, index); } /** * @return the interfaces this class is declared to implement * (not those inherited from its superclass/superinterfaces). */ public synchronized ClassType[] getInterfaces() { if (interfaces == null && (flags & EXISTING_CLASS) != 0 && getReflectClass() != null) { Class[] reflectInterfaces = reflectClass.getInterfaces(); int numInterfaces = reflectInterfaces.length; interfaces = numInterfaces == 0 ? noClasses : new ClassType[numInterfaces]; for (int i = 0; i < numInterfaces; i++) interfaces[i] = (ClassType) Type.make(reflectInterfaces[i]); } return interfaces; } public void setInterfaces (ClassType[] interfaces) { this.interfaces = interfaces; } /** Add an interface to the list of implemented interfaces. */ public void addInterface (ClassType newInterface) { int oldCount; if (interfaces == null || interfaces.length == 0) { oldCount = 0; interfaces = new ClassType[1]; } else { oldCount = interfaces.length; for (int i = oldCount; --i >= 0; ) if (interfaces[i] == newInterface) return; ClassType[] newInterfaces = new ClassType[oldCount+1]; System.arraycopy(interfaces, 0, newInterfaces, 0, oldCount); interfaces = newInterfaces; } interfaces[oldCount] = newInterface; } public final boolean isInterface() { return (getModifiers() & Access.INTERFACE) != 0; } public final void setInterface(boolean val) { if (val) access_flags |= Access.INTERFACE; else access_flags &= ~Access.INTERFACE; } public ClassType () { } public ClassType (String class_name) { super(); setName(class_name); } Field fields; int fields_count; Field last_field; /** Constant pool index of "ConstantValue". */ int ConstantValue_name_index; /** Constant pool index of "Code". */ int Code_name_index; /** Constant pool index of "LocalVariableTable". */ int LocalVariableTable_name_index; /** Constant pool index of "LineNumberTable". */ int LineNumberTable_name_index; /** Get the fields of this class. */ public final synchronized Field getFields() { if ((flags & (ADD_FIELDS_DONE|EXISTING_CLASS)) == EXISTING_CLASS) addFields(); return fields; } public final int getFieldCount() { return fields_count; } /** Find a field with the given name declared in this class. * @return the matching field, or null if there is no such field. */ public Field getDeclaredField(String name) { for (Field field = getFields(); field != null; field = field.next) { if (name.equals(field.name)) return field; } return null; } /** Find a field with the given name declared in this class or its ancestors. * @return the matching field, or null if there is no such field. */ public Field getField(String name) { ClassType cl = this; for (;;) { Field field = cl.getDeclaredField(name); if (field != null) return field; cl = cl.getSuperclass(); if (cl == null) return null; } } /** * Add a new field to this class. */ public Field addField () { return new Field (this); } /** * Add a new field to this class, and name the field. * @param name the name of the new field */ public Field addField (String name) { Field field = new Field (this); field.setName(name); return field; } public final Field addField (String name, Type type) { Field field = new Field (this); field.setName(name); field.setType(type); return field; } public final Field addField (String name, Type type, int flags) { Field field = addField (name, type); field.flags = flags; return field; } /** Use reflection to add all the declared fields of this class. * Does not add private or package-private fields. * Does not check for duplicate (already-known) fields. * Is not thread-safe if another thread may access this ClassType. */ public void addFields() { Class clas = getReflectClass(); java.lang.reflect.Field[] fields; try { fields = clas.getDeclaredFields(); } catch (SecurityException ex) { fields = clas.getFields(); } int count = fields.length; for (int i = 0; i < count; i++) { java.lang.reflect.Field field = fields[i]; if (! field.getDeclaringClass().equals(clas)) continue; int modifiers = field.getModifiers(); if ((modifiers & (Access.PUBLIC|Access.PROTECTED)) == 0) continue; addField(field.getName(), Type.make(field.getType()), modifiers); } flags |= ADD_FIELDS_DONE; } Method methods; int methods_count; Method last_method; public Method constructor; /** Get the methods of this class. */ public final Method getMethods() { return methods; } public final int getMethodCount() { return methods_count; } Method addMethod () { return new Method (this, 0); } public Method addMethod (String name) { Method method = new Method (this, 0); method.setName(name); return method; } public Method addMethod (String name, int flags) { Method method = new Method (this, flags); method.setName(name); return method; } // deprecated: public Method addMethod (String name, Type[] arg_types, Type return_type, int flags) { return addMethod(name, flags, arg_types, return_type); } /** Add a method to this ClassType. * If an existing method matches, return that. Otherwise, create * a new one. * In contrast, the other addMethod methods always create new Methods. */ public Method addMethod (String name, int flags, Type[] arg_types, Type return_type) { Method method = getDeclaredMethod(name, arg_types); if (method != null && return_type.equals(method.getReturnType()) && (flags & method.access_flags) == flags) return method; method = new Method (this, flags); method.setName(name); method.arg_types = arg_types; method.return_type = return_type; return method; } public Method addMethod (String name, String signature, int flags) { Method meth = addMethod(name, flags); meth.setSignature(signature); return meth; } /** Add a method to this ClassType. * If an existing method matches, return that. Otherwise, create * a new one. */ public Method getMethod (java.lang.reflect.Method method) { String name = method.getName(); Class[] parameterClasses = method.getParameterTypes(); Type[] parameterTypes = new Type[parameterClasses.length]; for (int i = parameterClasses.length; --i >= 0; ) parameterTypes[i] = Type.make(parameterClasses[i]); return addMethod(name, method.getModifiers(), parameterTypes, Type.make(method.getReturnType())); } public final synchronized Method getDeclaredMethods() { if ((flags & (ADD_METHODS_DONE|EXISTING_CLASS)) == EXISTING_CLASS) addMethods(getReflectClass()); return methods; } /** Count methods matching a given filter. * @param filter to select methods to return * @param searchSupers 0 if only current class should be searched, * 1 if superclasses should also be searched, * 2 if super-interfaces should also be search * @return number of methods that match */ public final int countMethods (Filter filter, int searchSupers) { return getMethods(filter, searchSupers, null, 0); } public Method[] getMethods (Filter filter, boolean searchSupers) { return getMethods(filter, searchSupers ? 1 : 0); } /** Get methods matching a given filter. * @param filter to select methods to return * @param searchSupers 0 if only current class should be searched, * 1 if superclasses should also be searched, * 2 if super-interfaces should also be searched * @return a fresh array containing the methods satisfying the filter */ public Method[] getMethods (Filter filter, int searchSupers) { int count = getMethods(filter, searchSupers, null, 0); Method[] result = new Method[count]; getMethods(filter, searchSupers, result, 0); return result; } /** Helper to get methods satisfying a filtering predicate. * @param filter to select methods to return * @param searchSupers 0 if only current class should be searched, * 1 if superclasses should also be searched, * 2 if super-interfaces should also be search
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -