|
|
@ -48,26 +48,41 @@ import java.lang.reflect.Method; |
|
|
|
import java.lang.reflect.Modifier; |
|
|
|
import java.lang.reflect.Modifier; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Accesses, creates or modifies java bytecode classes or interfaces. |
|
|
|
* Represents a class or interface. It can't be used for primitive |
|
|
|
* This class represents a class or interface, it can't be used for |
|
|
|
* or array types. Every class/interface is associated with a class
|
|
|
|
* primitive or array types. Every class/interface is associated with |
|
|
|
* path, which is used to load the class and its dependent classes. |
|
|
|
* a class path, which is used to load the class in memory. |
|
|
|
|
|
|
|
* |
|
|
|
* |
|
|
|
* <h3>Creating a class</h3> |
|
|
|
* <h3>ClassInfo and ClassPath</h3> |
|
|
|
* You create a new ClassInfo, by calling {@link |
|
|
|
* |
|
|
|
* ClassPath#getClassInfo}. The resulting ClassInfo is empty and you |
|
|
|
* Every ClassInfo instance belongs to a {@link ClassPath}. This |
|
|
|
* now have two different possibilities to fill it with informations: |
|
|
|
* class path is used to find the class and its dependent classes, |
|
|
|
* You load the class from its classpath (from which it was created) |
|
|
|
* e.g. the super class. Even if you want to create a class info from |
|
|
|
* or you build it from scratch by setting its contents with the |
|
|
|
* the scratch you have to associate it with a class path, in which |
|
|
|
* various <code>setSomething</code> methods. |
|
|
|
* the dependent classes are searched. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* For every class path and every class name there exists at most one |
|
|
|
|
|
|
|
* class info object with this class name. The only exception is when |
|
|
|
|
|
|
|
* you overwrite a loaded class, e.g. by calling setName(). |
|
|
|
* |
|
|
|
* |
|
|
|
* <h3>Changing a class</h3> |
|
|
|
* <h3>Creating a Class</h3> |
|
|
|
* Even if the class is already filled with information you can change |
|
|
|
* As you can see, there is no public constructor. Instead you create |
|
|
|
* it. You can, for example, set another array of methods, change the |
|
|
|
* a new ClassInfo, by calling {@link ClassPath#getClassInfo}. |
|
|
|
* modifiers, or rename the class. Use the various |
|
|
|
* Multiple calls of this method with the same class name result in |
|
|
|
* <code>setSomething</code> methods. |
|
|
|
* the same object. The resulting ClassInfo is initially empty and |
|
|
|
|
|
|
|
* you now have three different means to fill it with informations: |
|
|
|
|
|
|
|
* You can {@link #load load} the class from its classpath (from which |
|
|
|
|
|
|
|
* it was created), you can {@link #guess guess} the information |
|
|
|
|
|
|
|
* (useful if the class can't be loaded), or you build it from scratch |
|
|
|
|
|
|
|
* by setting its contents with the various <code>setSomething</code> |
|
|
|
|
|
|
|
* methods. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* <h3>Changing a Class</h3> |
|
|
|
|
|
|
|
* Whether or not the classinfo was already filled with information, |
|
|
|
|
|
|
|
* you can change it. You can, for example, provide another array of |
|
|
|
|
|
|
|
* methods, change the modifiers, or rename the class. Use the |
|
|
|
|
|
|
|
* various <code>setSomething</code> methods. |
|
|
|
* |
|
|
|
* |
|
|
|
* <h3>The components of a class</h3> |
|
|
|
* <h3>The Components of a Class</h3> |
|
|
|
* A class consists of several components: |
|
|
|
* A class consists of several components: |
|
|
|
* <dl> |
|
|
|
* <dl> |
|
|
|
* <dt>name</dt><dd> |
|
|
|
* <dt>name</dt><dd> |
|
|
@ -94,21 +109,20 @@ import java.lang.reflect.Modifier; |
|
|
|
* <dt>modifiers</dt><dd> |
|
|
|
* <dt>modifiers</dt><dd> |
|
|
|
* There is a set of access modifiers (AKA access flags) attached to |
|
|
|
* There is a set of access modifiers (AKA access flags) attached to |
|
|
|
* each class. They are represented as integers (bitboard) and can |
|
|
|
* each class. They are represented as integers (bitboard) and can |
|
|
|
* be conveniently accessed via |
|
|
|
* be conveniently accessed via {@link java.lang.reflect.Modifier}. |
|
|
|
* <code>java.lang.reflect.Modifier</code>. <br> <br> |
|
|
|
* <br> |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* Inner classes can have more modifiers than normal classes, as |
|
|
|
|
|
|
|
* they can be private, protected or static. These extended modifiers |
|
|
|
|
|
|
|
* are supported, too. <br> |
|
|
|
* |
|
|
|
* |
|
|
|
* Inner classes can have more modifiers than normal classes. To be |
|
|
|
* <b>TODO:</b> Check that reflection returns the extended modifiers! |
|
|
|
* backwards compatible this was implemented by Sun by having the real |
|
|
|
|
|
|
|
* modifiers for inner classes at a special location, while the old |
|
|
|
|
|
|
|
* location has only the modifiers that were allowed previously. |
|
|
|
|
|
|
|
* This package knows about this and always returns the real modifiers. |
|
|
|
|
|
|
|
* The old modifiers are checked if they match the new extended ones.<br> |
|
|
|
|
|
|
|
* <b>TODO:</b> Check that reflection returns the new modifiers! |
|
|
|
|
|
|
|
* </dd> |
|
|
|
* </dd> |
|
|
|
* <dt>superclass</dt><dd> |
|
|
|
* <dt>superclass</dt><dd> |
|
|
|
* Every class except java.lang.Object has a super class. The super class
|
|
|
|
* Every class except <code>java.lang.Object</code> has a super |
|
|
|
* is created in the same classpath as the current class. Interfaces |
|
|
|
* class. The super class is created in the same classpath as the |
|
|
|
* always have <code>java.lang.Object</code> as their super class. |
|
|
|
* current class. Interfaces always have |
|
|
|
|
|
|
|
* <code>java.lang.Object</code> as their super class. |
|
|
|
* </dd> |
|
|
|
* </dd> |
|
|
|
* <dt>interfaces</dt><dd> |
|
|
|
* <dt>interfaces</dt><dd> |
|
|
|
* Every class (resp. interfaces) can implement (resp. extend) |
|
|
|
* Every class (resp. interfaces) can implement (resp. extend) |
|
|
@ -118,61 +132,62 @@ import java.lang.reflect.Modifier; |
|
|
|
* Fields are represented as {@link FieldInfo} objects. |
|
|
|
* Fields are represented as {@link FieldInfo} objects. |
|
|
|
* </dd> |
|
|
|
* </dd> |
|
|
|
* <dt>methods</dt><dd> |
|
|
|
* <dt>methods</dt><dd> |
|
|
|
* Fields are represented as {@link MethodInfo} objects. |
|
|
|
* Methods are represented as {@link MethodInfo} objects. |
|
|
|
* </dd> |
|
|
|
* </dd> |
|
|
|
* <dt>method scoped</dt><dd> |
|
|
|
* <dt>method scoped</dt><dd> |
|
|
|
* A boolean value; true if this class is an anonymous or method |
|
|
|
* A boolean value; true if this class is an anonymous or method |
|
|
|
* scoped class. |
|
|
|
* scoped class. |
|
|
|
* </dd> |
|
|
|
* </dd> |
|
|
|
* <dt>outer class</dt><dd> |
|
|
|
* <dt>outer class</dt><dd> |
|
|
|
* the class of which this class is the inner class. It returns |
|
|
|
* the class in which this class or interface was declared. It |
|
|
|
* null for package scoped and method scoped classes. <br> |
|
|
|
* returns null for package scoped and method scoped classes. |
|
|
|
* </dd> |
|
|
|
* </dd> |
|
|
|
* <dt>classes</dt><dd> |
|
|
|
* <dt>classes</dt><dd> |
|
|
|
* the inner classes which is an array of ClassInfo. This doesn't |
|
|
|
* the inner classes declared in this class. This doesn't include |
|
|
|
* include method scoped classes.<br> |
|
|
|
* method scoped classes. |
|
|
|
* </dd> |
|
|
|
* </dd> |
|
|
|
* <dt>source file</dt><dd> |
|
|
|
* <dt>source file</dt><dd> |
|
|
|
* The name of source file. The JVM uses this field when a stack |
|
|
|
* The name of source file. The JVM uses this field when a stack |
|
|
|
* trace is produced. |
|
|
|
* trace is produced. It may be null if the class was compiled |
|
|
|
|
|
|
|
* without debugging information. |
|
|
|
* </dd> |
|
|
|
* </dd> |
|
|
|
* </dl> |
|
|
|
* </dl> |
|
|
|
* |
|
|
|
* |
|
|
|
* <h3>inner classes</h3> |
|
|
|
* <h3>Inner Classes</h3> |
|
|
|
* Inner classes are supported as far as the information is present in |
|
|
|
* Inner classes are supported as far as the information is present in |
|
|
|
* the bytecode. But you can always ignore this inner information, |
|
|
|
* the bytecode. However, you can always ignore this inner |
|
|
|
* and access inner classes by their bytecode name, |
|
|
|
* information, and access inner classes by their bytecode name, |
|
|
|
* e.g. <code>java.util.Map$Entry</code>. There are four different types |
|
|
|
* e.g. <code>java.util.Map$Entry</code>. There are four different |
|
|
|
* of classes: |
|
|
|
* types of classes: |
|
|
|
* <dl> |
|
|
|
* <dl> |
|
|
|
* <dt>normal package scoped classes</dt><dd> |
|
|
|
* <dt>normal package scoped classes</dt><dd> |
|
|
|
* A class is package scoped if, and only if |
|
|
|
* A class is package scoped if, and only if |
|
|
|
* <code>getOuterClass()</code> returns <code>null</code> and |
|
|
|
* {@link #getOuterClass()} returns <code>null</code> and |
|
|
|
* <code>isMethodScoped()</code> returns <code>false</code>. |
|
|
|
* {@link #isMethodScoped()} returns <code>false</code>. |
|
|
|
* </dd> |
|
|
|
* </dd> |
|
|
|
* <dt>class scoped classes (inner classes)</dt><dd> |
|
|
|
* <dt>class scoped classes (inner classes)</dt><dd> |
|
|
|
* A class is class scoped if, and only if |
|
|
|
* A class is class scoped if, and only if |
|
|
|
* <code>getOuterClass()</code> returns not <code>null</code>. |
|
|
|
* {@link #getOuterClass()} returns not <code>null</code>. |
|
|
|
* |
|
|
|
* |
|
|
|
* The bytecode name (<code>getName()</code>) of an inner class is |
|
|
|
* The bytecode name ({@link #getName()}) of an inner class is |
|
|
|
* in most cases of the form <code>Package.Outer$Inner</code>. But |
|
|
|
* in normally of the form <code>Package.Outer$Inner</code>. However, |
|
|
|
* ClassInfo also supports differently named classes, as long as the |
|
|
|
* ClassInfo also supports differently named classes, as long as the |
|
|
|
* InnerClass attribute is present. The method |
|
|
|
* InnerClass attribute is present. The method |
|
|
|
* <code>getClassName()</code> returns the name of the inner class
|
|
|
|
* {@link #getClassName()} returns the name of the inner class
|
|
|
|
* (<code>Inner</code> in the above example). |
|
|
|
* (<code>Inner</code> in the above example). |
|
|
|
* |
|
|
|
* |
|
|
|
* You can get all inner classes of a class with the |
|
|
|
* You can get all inner classes of a class with the |
|
|
|
* <code>getClasses</code> method. |
|
|
|
* method {@link #getClasses}. |
|
|
|
* </dd> |
|
|
|
* </dd> |
|
|
|
* <dt>named method scoped classes</dt><dd> |
|
|
|
* <dt>named method scoped classes</dt><dd> |
|
|
|
* A class is a named method scoped class if, and only if |
|
|
|
* A class is a named method scoped class if, and only if |
|
|
|
* <code>isMethodScoped()</code> returns <code>true</code> and |
|
|
|
* {@link #isMethodScoped()} returns <code>true</code> and |
|
|
|
* <code>getClassName()</code> returns not <code>null</code>. In |
|
|
|
* {@link #getClassName()} returns not <code>null</code>. In |
|
|
|
* that case <code>getOuterClass()</code> returns <code>null</code>, |
|
|
|
* that case {@link #getOuterClass()} returns <code>null</code>, |
|
|
|
* too.<br><br> |
|
|
|
* too.<br><br> |
|
|
|
* |
|
|
|
* |
|
|
|
* The bytecode name (<code>getName()</code>) of an method scoped class is |
|
|
|
* The bytecode name ({@link #getName()}) of a method scoped class is |
|
|
|
* in most cases of the form <code>Package.Outer$Number$Inner</code>. But |
|
|
|
* normally of the form <code>Package.Outer$Number$Inner</code>. However, |
|
|
|
* ClassInfo also supports differently named classes, as long as the |
|
|
|
* ClassInfo also supports differently named classes, as long as the |
|
|
|
* InnerClass attribute is present. <br><br> |
|
|
|
* InnerClass attribute is present. <br><br> |
|
|
|
* |
|
|
|
* |
|
|
@ -182,16 +197,15 @@ import java.lang.reflect.Modifier; |
|
|
|
* </dd> |
|
|
|
* </dd> |
|
|
|
* <dt>anonymous classes</dt><dd> |
|
|
|
* <dt>anonymous classes</dt><dd> |
|
|
|
* A class is an anonymous class if, and only if |
|
|
|
* A class is an anonymous class if, and only if |
|
|
|
* <code>isMethodScoped()</code> returns <code>true</code> and |
|
|
|
* {@link #isMethodScoped()} returns <code>true</code> and |
|
|
|
* <code>getClassName()</code> returns <code>null</code>. In that |
|
|
|
* {@link #getClassName()} returns <code>null</code>. In that |
|
|
|
* case <code>getOuterClass()</code> returns <code>null</code>, |
|
|
|
* case {@link #getOuterClass()} returns <code>null</code>, |
|
|
|
* too.<br><br> |
|
|
|
* too.<br><br> |
|
|
|
* |
|
|
|
* |
|
|
|
* The bytecode name (<code>getName()</code>) of an method scoped |
|
|
|
* The bytecode name ({@link #getName()}) of a method scoped class
|
|
|
|
* class is in most cases of the form |
|
|
|
* is normally of the form <code>Package.Outer$Number</code>. |
|
|
|
* <code>Package.Outer$Number</code>. But ClassInfo also supports |
|
|
|
* However, ClassInfo also supports differently named classes, as |
|
|
|
* differently named classes, as long as the InnerClass attribute is |
|
|
|
* long as the InnerClass attribute is present. <br><br> |
|
|
|
* present. <br><br> |
|
|
|
|
|
|
|
* |
|
|
|
* |
|
|
|
* There's no way to get the anonymous classes of a method, except |
|
|
|
* There's no way to get the anonymous classes of a method, except |
|
|
|
* by analyzing its instructions. And even that is error prone, since |
|
|
|
* by analyzing its instructions. And even that is error prone, since |
|
|
@ -200,22 +214,21 @@ import java.lang.reflect.Modifier; |
|
|
|
* </dl> |
|
|
|
* </dl> |
|
|
|
* |
|
|
|
* |
|
|
|
* <hr> |
|
|
|
* <hr> |
|
|
|
* <h3>Open Questions</h3> |
|
|
|
* <h3>Open Question</h3> |
|
|
|
* |
|
|
|
* |
|
|
|
* I represent most types as <code>java/lang/String</code> (type |
|
|
|
* I represent most types as {@link String} objects (type |
|
|
|
* signatures); this is convenient since java bytecode does the same. |
|
|
|
* signatures); this is convenient since java bytecode does the same. |
|
|
|
* On the other hand a class type should be represented as |
|
|
|
* On the other hand a class type should be represented as |
|
|
|
* <code>jode/bytecode/ClassInfo</code> class. There should be a |
|
|
|
* {@link ClassInfo} object. There is a method in {@link TypeSignature} |
|
|
|
* method to convert to it, but I need a ClassPath for this. Should |
|
|
|
* to convert between them, which needs a class path. This is a |
|
|
|
* the method be in ClassInfo (I don't think so), should an instance |
|
|
|
* bit difficult to use. <br> |
|
|
|
* of TypeSignature have a ClassPath as member variable, or should |
|
|
|
|
|
|
|
* getClassInfo() take a ClassPath parameter as it is currently? |
|
|
|
|
|
|
|
* What about arrays, shall we support special ClassInfo's for them, |
|
|
|
|
|
|
|
* as java.lang.Class does? I think the current solution is okay. |
|
|
|
|
|
|
|
* <br> |
|
|
|
|
|
|
|
* |
|
|
|
* |
|
|
|
* @author Jochen Hoenicke |
|
|
|
* However the alternative would be to represents types as ClassInfo |
|
|
|
*/ |
|
|
|
* and create ClassInfo objects for primitive and array types. But |
|
|
|
|
|
|
|
* this contradicts the purpose of this class, which is to read and |
|
|
|
|
|
|
|
* write class files. I think the current solution is okay. <br> |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @author Jochen Hoenicke */ |
|
|
|
public final class ClassInfo extends BinaryInfo implements Comparable { |
|
|
|
public final class ClassInfo extends BinaryInfo implements Comparable { |
|
|
|
|
|
|
|
|
|
|
|
private static ClassPath defaultClasspath; |
|
|
|
private static ClassPath defaultClasspath; |
|
|
@ -250,16 +263,15 @@ public final class ClassInfo extends BinaryInfo implements Comparable { |
|
|
|
public static final int NONE = 0; |
|
|
|
public static final int NONE = 0; |
|
|
|
/** |
|
|
|
/** |
|
|
|
* This constant can be used as parameter to load. It specifies |
|
|
|
* This constant can be used as parameter to load. It specifies |
|
|
|
* that at least the outer class information should be loaded, i.e. |
|
|
|
* that at least the outer class information should be loaded, |
|
|
|
* the outer class, the class name. It is the |
|
|
|
* i.e. the outer class and the java class name. It is the only |
|
|
|
* only information that is loaded recursively: It is also |
|
|
|
* information that is loaded recursively: It is also |
|
|
|
* automatically loaded for the outer class and it is loaded for |
|
|
|
* automatically loaded for all classes that are accessed by this |
|
|
|
* all inner and extra classes, if these fields are loaded. |
|
|
|
* class. The reason for the recursive load is simple: In java |
|
|
|
* The reason for the recursive load is simple: In java bytecode |
|
|
|
* bytecode a class contains the outer class information for all |
|
|
|
* a class contains the outer class information for all outer, |
|
|
|
* classes that it accesses, so we can create this information |
|
|
|
* inner and extra classes, so we can create this information |
|
|
|
|
|
|
|
* without the need to read the outer class. We also need this |
|
|
|
* without the need to read the outer class. We also need this |
|
|
|
* information for outer and inner classes when writing a class. |
|
|
|
* information when writing a class. |
|
|
|
* |
|
|
|
* |
|
|
|
* @see #load |
|
|
|
* @see #load |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -355,6 +367,14 @@ public final class ClassInfo extends BinaryInfo implements Comparable { |
|
|
|
return defaultClasspath.getClassInfo(name); |
|
|
|
return defaultClasspath.getClassInfo(name); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Disable the default constructor. |
|
|
|
|
|
|
|
* @exception InternalError always. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private ClassInfo() throws InternalError { |
|
|
|
|
|
|
|
throw new InternalError(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ClassInfo(String name, ClassPath classpath) { |
|
|
|
ClassInfo(String name, ClassPath classpath) { |
|
|
|
/* Name may be null when reading class with unknown name from |
|
|
|
/* Name may be null when reading class with unknown name from |
|
|
|
* stream. |
|
|
|
* stream. |
|
|
@ -936,22 +956,21 @@ public final class ClassInfo extends BinaryInfo implements Comparable { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Loads the contents of a class from the classpath. |
|
|
|
* Loads the contents of a class from its class path. |
|
|
|
* @param howMuch The amount of information that should be read |
|
|
|
* @param howMuch The amount of information that should be loaded |
|
|
|
* in, one of <code>HIERARCHY</code>, |
|
|
|
* at least, one of {@link #OUTERCLASS}, {@link #HIERARCHY}, {@link |
|
|
|
* <code>PUBLICDECLARATIONS</code>, |
|
|
|
* #PUBLICDECLARATIONS}, {@link #DECLARATIONS}, {@link #NODEBUG}, |
|
|
|
* <code>DECLARATIONS</code>, <code>ALMOSTALL</code> |
|
|
|
* {@link #ALMOSTALL} or {@link #ALL}. Note that more information |
|
|
|
* or <code>ALL</code>. |
|
|
|
* than requested can be loaded if this is convenient. |
|
|
|
* @exception ClassFormatException if the file doesn't denote a |
|
|
|
* @exception ClassFormatException if the file doesn't denote a |
|
|
|
* valid class. |
|
|
|
* valid class. |
|
|
|
* @exception FileNotFoundException if class wasn't found in classpath. |
|
|
|
* @exception FileNotFoundException if class wasn't found in classpath. |
|
|
|
* @exception IOException if an io exception occured. |
|
|
|
* @exception IOException if an io exception occured while reading |
|
|
|
* @exception IllegalStateException if this ClassInfo was modified. |
|
|
|
* the class. |
|
|
|
* @see #HIERARCHY |
|
|
|
* @exception SecurityException if a security manager prohibits loading |
|
|
|
* @see #PUBLICDECLARATIONS |
|
|
|
* the class. |
|
|
|
* @see #DECLARATIONS |
|
|
|
* @exception IllegalStateException if this ClassInfo was modified by |
|
|
|
* @see #ALMOSTALL |
|
|
|
* calling one of the setSomething methods. |
|
|
|
* @see #ALL |
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void load(int howMuch) |
|
|
|
public void load(int howMuch) |
|
|
|
throws IOException |
|
|
|
throws IOException |
|
|
@ -975,8 +994,8 @@ public final class ClassInfo extends BinaryInfo implements Comparable { |
|
|
|
* extends java.lang.Object, implements no interfaces and has no |
|
|
|
* extends java.lang.Object, implements no interfaces and has no |
|
|
|
* fields, methods or inner classes. |
|
|
|
* fields, methods or inner classes. |
|
|
|
* |
|
|
|
* |
|
|
|
* @param howMuch The amount of information that should be read, e.g. |
|
|
|
* @param howMuch The amount of information that should be read, |
|
|
|
* <code>HIERARCHY</code>. |
|
|
|
* e.g. {@link #HIERARCHY}. |
|
|
|
* @see #OUTERCLASS |
|
|
|
* @see #OUTERCLASS |
|
|
|
* @see #HIERARCHY |
|
|
|
* @see #HIERARCHY |
|
|
|
* @see #PUBLICDECLARATIONS |
|
|
|
* @see #PUBLICDECLARATIONS |
|
|
@ -1035,9 +1054,11 @@ public final class ClassInfo extends BinaryInfo implements Comparable { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* This is the counter part to load and guess. It will drop all |
|
|
|
* This is the counter part to load and guess. It will drop all |
|
|
|
* informations bigger than "keep" and clean up the memory. |
|
|
|
* informations bigger than "keep" and clean up the memory. Note |
|
|
|
|
|
|
|
* that drop should be used with care if more than one thread |
|
|
|
|
|
|
|
* accesses this ClassInfo. |
|
|
|
* @param keep tells how much info we should keep, can be |
|
|
|
* @param keep tells how much info we should keep, can be |
|
|
|
* <code>NONE</code> or anything that <code>load</code> accepts. |
|
|
|
* {@link #NONE} or anything that <code>load</code> accepts. |
|
|
|
* @see #load |
|
|
|
* @see #load |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void drop(int keep) { |
|
|
|
public void drop(int keep) { |
|
|
@ -1091,6 +1112,11 @@ public final class ClassInfo extends BinaryInfo implements Comparable { |
|
|
|
return name; |
|
|
|
return name; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Tells whether the information in this class was guessed by a call |
|
|
|
|
|
|
|
* to {@link #guess}. |
|
|
|
|
|
|
|
* @return true if the information was guessed. |
|
|
|
|
|
|
|
*/ |
|
|
|
public boolean isGuessed() { |
|
|
|
public boolean isGuessed() { |
|
|
|
return isGuessed; |
|
|
|
return isGuessed; |
|
|
|
} |
|
|
|
} |
|
|
@ -1142,16 +1168,37 @@ public final class ClassInfo extends BinaryInfo implements Comparable { |
|
|
|
return interfaces; |
|
|
|
return interfaces; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Gets the modifiers of this class, e.g. public or abstract. The |
|
|
|
|
|
|
|
* information is only available if at least {@link #HIERARCHY} is |
|
|
|
|
|
|
|
* loaded. |
|
|
|
|
|
|
|
* @return a bitboard of the modifiers. |
|
|
|
|
|
|
|
* @see Class#getModifiers |
|
|
|
|
|
|
|
* @see Modifier |
|
|
|
|
|
|
|
*/ |
|
|
|
public int getModifiers() { |
|
|
|
public int getModifiers() { |
|
|
|
if (modifiers == -1) |
|
|
|
if (modifiers == -1) |
|
|
|
throw new IllegalStateException("status is "+status); |
|
|
|
throw new IllegalStateException("status is "+status); |
|
|
|
return modifiers; |
|
|
|
return modifiers; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Checks whether this class info represents an interface. The |
|
|
|
|
|
|
|
* information is only available if at least {@link #HIERARCHY} is |
|
|
|
|
|
|
|
* loaded. |
|
|
|
|
|
|
|
* @return true if this class info represents an interface. |
|
|
|
|
|
|
|
*/ |
|
|
|
public boolean isInterface() { |
|
|
|
public boolean isInterface() { |
|
|
|
return Modifier.isInterface(getModifiers()); |
|
|
|
return Modifier.isInterface(getModifiers()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Searches for a field with given name and type signature. |
|
|
|
|
|
|
|
* @param name the name of the field. |
|
|
|
|
|
|
|
* @param typeSig the {@link TypeSignature type signature} of the |
|
|
|
|
|
|
|
* field. |
|
|
|
|
|
|
|
* @return the field info for the field. |
|
|
|
|
|
|
|
*/ |
|
|
|
public FieldInfo findField(String name, String typeSig) { |
|
|
|
public FieldInfo findField(String name, String typeSig) { |
|
|
|
if (status < PUBLICDECLARATIONS) |
|
|
|
if (status < PUBLICDECLARATIONS) |
|
|
|
throw new IllegalStateException("status is "+status); |
|
|
|
throw new IllegalStateException("status is "+status); |
|
|
@ -1162,6 +1209,13 @@ public final class ClassInfo extends BinaryInfo implements Comparable { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Searches for a method with given name and type signature. |
|
|
|
|
|
|
|
* @param name the name of the method. |
|
|
|
|
|
|
|
* @param typeSig the {@link TypeSignature type signature} of the |
|
|
|
|
|
|
|
* method. |
|
|
|
|
|
|
|
* @return the method info for the method. |
|
|
|
|
|
|
|
*/ |
|
|
|
public MethodInfo findMethod(String name, String typeSig) { |
|
|
|
public MethodInfo findMethod(String name, String typeSig) { |
|
|
|
if (status < PUBLICDECLARATIONS) |
|
|
|
if (status < PUBLICDECLARATIONS) |
|
|
|
throw new IllegalStateException("status is "+status); |
|
|
|
throw new IllegalStateException("status is "+status); |
|
|
@ -1172,12 +1226,18 @@ public final class ClassInfo extends BinaryInfo implements Comparable { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Gets the methods of this class. |
|
|
|
|
|
|
|
*/ |
|
|
|
public MethodInfo[] getMethods() { |
|
|
|
public MethodInfo[] getMethods() { |
|
|
|
if (status < PUBLICDECLARATIONS) |
|
|
|
if (status < PUBLICDECLARATIONS) |
|
|
|
throw new IllegalStateException("status is "+status); |
|
|
|
throw new IllegalStateException("status is "+status); |
|
|
|
return methods; |
|
|
|
return methods; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Gets the fields (class and member variables) of this class. |
|
|
|
|
|
|
|
*/ |
|
|
|
public FieldInfo[] getFields() { |
|
|
|
public FieldInfo[] getFields() { |
|
|
|
if (status < PUBLICDECLARATIONS) |
|
|
|
if (status < PUBLICDECLARATIONS) |
|
|
|
throw new IllegalStateException("status is "+status); |
|
|
|
throw new IllegalStateException("status is "+status); |
|
|
@ -1200,7 +1260,7 @@ public final class ClassInfo extends BinaryInfo implements Comparable { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Returns true if the class was declared inside a method. |
|
|
|
* Tells whether the class was declared inside a method. |
|
|
|
* This needs the OUTERCLASS information loaded. |
|
|
|
* This needs the OUTERCLASS information loaded. |
|
|
|
* @return true if this is a method scoped or an anonymous class, |
|
|
|
* @return true if this is a method scoped or an anonymous class, |
|
|
|
* false otherwise. |
|
|
|
* false otherwise. |
|
|
@ -1215,11 +1275,12 @@ public final class ClassInfo extends BinaryInfo implements Comparable { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Returns the inner classes declared in this class. |
|
|
|
* Gets the inner classes declared in this class. |
|
|
|
* This needs at least PUBLICDECLARATION information loaded. |
|
|
|
* This needs at least PUBLICDECLARATION information loaded. |
|
|
|
* @return an array containing the inner classes, guaranteed != null. |
|
|
|
* @return an array containing the inner classes, guaranteed != null. |
|
|
|
* @exception IllegalStateException if PUBLICDECLARATIONS information |
|
|
|
* @exception IllegalStateException if PUBLICDECLARATIONS information |
|
|
|
* wasn't loaded yet. */ |
|
|
|
* wasn't loaded yet. |
|
|
|
|
|
|
|
*/ |
|
|
|
public ClassInfo[] getClasses() { |
|
|
|
public ClassInfo[] getClasses() { |
|
|
|
if (status < PUBLICDECLARATIONS) |
|
|
|
if (status < PUBLICDECLARATIONS) |
|
|
|
throw new IllegalStateException("status is "+status); |
|
|
|
throw new IllegalStateException("status is "+status); |
|
|
@ -1457,6 +1518,10 @@ public final class ClassInfo extends BinaryInfo implements Comparable { |
|
|
|
return clazz == this; |
|
|
|
return clazz == this; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Returns a string representation of the class. This is just the |
|
|
|
|
|
|
|
* full qualified class name. |
|
|
|
|
|
|
|
*/ |
|
|
|
public String toString() { |
|
|
|
public String toString() { |
|
|
|
return name; |
|
|
|
return name; |
|
|
|
} |
|
|
|
} |
|
|
|