From 5e24bfce86fd3d9b660837f6fae63388621c295d Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 26 Jun 1999 16:15:44 +0000 Subject: [PATCH] comments reworked git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@906 379699f6-c40d-0410-875b-85095c16579e --- jode/jode/type/Type.java | 322 +++++++++++++++++++++++++++++++-------- 1 file changed, 255 insertions(+), 67 deletions(-) diff --git a/jode/jode/type/Type.java b/jode/jode/type/Type.java index 0570fc9..92ec546 100644 --- a/jode/jode/type/Type.java +++ b/jode/jode/type/Type.java @@ -31,55 +31,15 @@ import java.util.Hashtable; ///#endif /** - * This is my type class. It differs from java.lang.class, in - * that it maintains a type range. This type range may be implicit or - * explicit.
+ * This is my type class. It differs from java.lang.class, in that it + * represents a set of types. Since most times this set is infinite, it + * needs a special representation.
* - * - * Think of this global type hierarchie: - *
- *
- *          tUnknown
- *          /   |   \
- *         /    |    \
- *  tObject  boolean  int
- *    /  \            /  \
- *   /  tArray     short char
- * other             | 
- * classes          byte 
- * 
- * - * int implements the "interface" tBoolInt. boolean and byte - * implement the "interface" tBoolByte which extends tBoolInt.
- * - * The type tBoolInt is , the type tBoolByte is - * (hard coded in getTop). The - * type tUInt is .
- * - * Note that tUnknown is no valid type, so we can replace - * with - * with ,
- * - * Arrays extend Object and implement java.lang.Cloneable and - * java.io.Serializable, as defined in jls. - * - * The main operation on a type range is the intersection. To do this - * on class ranges we need three more operations: specialization, - * generalization and createRange.

- * - * specialization chooses the common sub type of the two types. It - * is used to find the start point of the intersected interval.

- * - * generalization chooses the common super type of two types. It - * is used to find the end point of the intersected interval.

- * - * When the new interval is created with createRangeType - * the start and end points are adjusted so that they only consists of - * possible types. + * The main operation on a type sets are tSuperType, tSubType and + * intersection. * * @author Jochen Hoenicke */ public class Type { - public static final int TC_BOOLEAN = 0; public static final int TC_BYTE = 1; public static final int TC_CHAR = 2; @@ -111,38 +71,114 @@ public class Type { private static final Hashtable methodHash = new Hashtable(); ///#endif + /** + * This type represents the singleton set containing the boolean type. + */ public static final Type tBoolean = new IntegerType(IntegerType.IT_Z); + /** + * This type represents the singleton set containing the byte type. + */ public static final Type tByte = new IntegerType(IntegerType.IT_B); + /** + * This type represents the singleton set containing the char type. + */ public static final Type tChar = new IntegerType(IntegerType.IT_C); + /** + * This type represents the singleton set containing the short type. + */ public static final Type tShort = new IntegerType(IntegerType.IT_S); + /** + * This type represents the singleton set containing the int type. + */ public static final Type tInt = new IntegerType(IntegerType.IT_I); + /** + * This type represents the singleton set containing the long type. + */ public static final Type tLong = new Type(TC_LONG); + /** + * This type represents the singleton set containing the float type. + */ public static final Type tFloat = new Type(TC_FLOAT); + /** + * This type represents the singleton set containing the double type. + */ public static final Type tDouble = new Type(TC_DOUBLE); + /** + * This type represents the void type. It is really not a type at + * all. + */ public static final Type tVoid = new Type(TC_VOID); + /** + * This type represents the empty set, and probably means, that something + * has gone wrong. + */ public static final Type tError = new Type(TC_ERROR); + /** + * This type represents the set of all possible types. + */ public static final Type tUnknown = new Type(TC_UNKNOWN); + /** + * This type represents the set of all integer types, up to 32 bit. + */ public static final Type tUInt = new IntegerType(IntegerType.IT_I | IntegerType.IT_B | IntegerType.IT_C | IntegerType.IT_S); + /** + * This type represents the set of the boolean and int type. + */ public static final Type tBoolInt = new IntegerType(IntegerType.IT_I | IntegerType.IT_Z); + /** + * This type represents the set of boolean and all integer types, + * up to 32 bit. + */ public static final Type tBoolUInt= new IntegerType(IntegerType.IT_I | IntegerType.IT_B | IntegerType.IT_C | IntegerType.IT_S | IntegerType.IT_Z); + /** + * This type represents the set of the boolean and byte type. + */ public static final Type tBoolByte= new IntegerType(IntegerType.IT_B | IntegerType.IT_Z); + /** + * This type represents the singleton set containing + * java.lang.Object. + */ public static final ClassInterfacesType tObject = tClass("java.lang.Object"); + /** + * This type represents the singleton set containing the special + * null type (the type of null). + */ public static final ReferenceType tNull = new NullType(); + /** + * This type represents the set of all reference types, including + * class types, array types, interface types and the null type. + */ public static final Type tUObject = tRange(tObject, tNull); + /** + * This type represents the singleton set containing + * java.lang.String. + */ public static final Type tString = tClass("java.lang.String"); + /** + * This type represents the singleton set containing + * java.lang.StringBuffer. + */ public static final Type tStringBuffer = tClass("java.lang.StringBuffer"); + /** + * This type represents the singleton set containing + * java.lang.Class. + */ public static final Type tJavaLangClass = tClass("java.lang.Class"); + /** + * This is a private method for generating the signature of a + * given type. + */ private static final StringBuffer appendSignature(StringBuffer sb, Class javaType) { if (javaType.isPrimitive()) { @@ -175,10 +211,24 @@ public class Type { } } + /** + * Generate the signature for the given Class. + * @param clazz a java.lang.Class, this may also be a primitive or + * array type. + * @return the type signature (see section 4.3.2 Field Descriptors + * of the JVM specification) + */ public static String getSignature(Class clazz) { return appendSignature(new StringBuffer(), clazz).toString(); } + /** + * Generate a method signature. + * @param paramT the java.lang.Class of the parameter types of the method. + * @param returnT the java.lang.Class of the return type of the method. + * @return the method signature (see section 4.3.3 Method Descriptors + * of the JVM specification) + */ public static String getSignature(Class paramT[], Class returnT) { StringBuffer sig = new StringBuffer("("); for (int i=0; i< paramT.length; i++) @@ -186,6 +236,12 @@ public class Type { return appendSignature(sig.append(')'), returnT).toString(); } + /** + * Generate the singleton set of the type represented by the given + * string. + * @param type the type signature (or method signature). + * @return a singleton set containing the given type. + */ public static final Type tType(String type) { if (type == null || type.length() == 0) return tError; @@ -221,14 +277,33 @@ public class Type { throw new AssertError("Unknown type signature: "+type); } + /** + * Generate the singleton set of the type represented by the given + * class. + * @param javaType the type class. + * @return a singleton set containing the given type. + */ public static final Type tType(Class javaType) { return Type.tType(getSignature(javaType)); } + /** + * Generate the singleton set of the type represented by the given + * class name. + * @param clazzname the full qualified name of the class. + * The packages may be separated by `.' or `/'. + * @return a singleton set containing the given type. + */ public static final ClassInterfacesType tClass(String clazzname) { return tClass(ClassInfo.forName(clazzname.replace('/','.'))); } + /** + * Generate the singleton set of the type represented by the given + * class info. + * @param clazzinfo the jode.bytecode.ClassInfo. + * @return a singleton set containing the given type. + */ public static final ClassInterfacesType tClass(ClassInfo clazzinfo) { ///#ifdef JDK12 /// java.lang.ref.Reference died; @@ -250,6 +325,12 @@ public class Type { return (ClassInterfacesType) result; } + /** + * Generate/look up the set of the array type whose element types + * are in the given type set. + * @param type the element types (which may be the empty set tError). + * @return the set of array types (which may be the empty set tError). + */ public static final Type tArray(Type type) { if (type == tError) return type; @@ -273,6 +354,11 @@ public class Type { return result; } + /** + * Generate/look up the method type for the given signature + * @param signature the method decriptor. + * @return a method type (a singleton set). + */ public static MethodType tMethod(String signature) { ///#ifdef JDK12 /// java.lang.ref.Reference died; @@ -293,23 +379,69 @@ public class Type { } return result; } + + /** + * Generate/look up the method type for the given class + * @param paramT the parameter types of the method. + * @param returnT the return type of the method. + * @return a method type (a singleton set). + */ public static MethodType tMethod(Class paramT[], Class returnT) { return tMethod(getSignature(paramT, returnT)); } + /** + * Generate the range type from bottom to top. This should + * represent all reference types, that can be casted to bottom by + * a widening cast and where top can be casted to. You should not + * use this method directly; use tSubType, tSuperType and + * intersection instead, which is more general. + * @param bottom the bottom type. + * @param top the top type. + * @return the range type. + */ public static final Type tRange(ReferenceType bottom, ReferenceType top) { return new RangeType(bottom, top); } - + + /** + * Generate the set of types, to which one of the types in type can + * be casted to by a widening cast. The following holds: + *

  • tSuperType(tObject) = tObject
  • + *
  • tSuperType(tError) = tError
  • + *
  • type.intersection(tSuperType(type)).equals(type) + * (this means type is a subset of tSuperType(type).
  • + *
  • tSuperType(tNull) = tUObject
  • + *
  • tSuperType(tChar) = {tChar, tInt }
+ * @param type a set of types. + * @return the super types of type. + */ public static Type tSuperType(Type type) { - return type.getSuperType(); + return type.getSuperType(); } + /** + * Generate the set of types, which can be casted to one of the + * types in type by a widening cast. The following holds: + *
  • tSubType(tObject) = tUObject
  • + *
  • tSubType(tError) = tError
  • + *
  • type.intersection(tSubType(type)).equals(type) + * (this means type is a subset of tSubType(type).
  • + *
  • tSuperType(tSubType(type)) is a subset of type
  • + *
  • tSubType(tSuperType(type)) is a subset of type
  • + *
  • tSubType(tNull) = tNull
  • + *
  • tSubType(tBoolean, tShort) = { tBoolean, tByte, tShort }
+ * @param type a set of types. + * @return the sub types of type. + */ public static Type tSubType(Type type) { return type.getSubType(); } - + + /** + * The typecode of this type. This should be one of the TC_ constants. + */ final int typecode; /** @@ -319,33 +451,59 @@ public class Type { typecode = tc; } + /** + * The sub types of this type. + * @return tSubType(this). + */ public Type getSubType() { return this; } + /** + * The super types of this type. + * @return tSuperType(this). + */ public Type getSuperType() { return this; } -// public Type getBottom() { -// return this; -// } - -// public Type getTop() { -// return this; -// } - + /** + * Returns the hint type of this type set. This returns the singleton + * set containing only the `most likely' type in this set. This doesn't + * work for tError or tUnknown, and may lead + * to errors for certain range types. + * @return the hint type. + */ public Type getHint() { + return getCanonic(); + } + + /** + * Returns the canonic type of this type set. The intention is, to + * return for each expression the type, that the java compiler would + * assign to this expression. + * @return the canonic type. + */ + public Type getCanonic() { return this; } /** - * @return the type code of the type. + * Returns the type code of this type. Don't use this; it is + * merily needed by the sub types (and the bytecode verifier, which + * has its own type merging methods). + * @return the type code of the type. */ public final int getTypeCode() { return typecode; } + /** + * Returns the number of stack/local entries an object of this type + * occupies. + * @return 0 for tVoid, 2 for tDouble and tLong and + * 1 for every other type. + */ public int stackSize() { switch(typecode) { @@ -361,9 +519,10 @@ public class Type { } /** - * Intersect this type with another type and return the new type. - * @param type the other type. - * @return the intersection, or tError, if a type conflict happens. + * Intersect this set of types with another type set and return the + * intersection. + * @param type the other type set. + * @return the intersection, tError, if the intersection is empty. */ public Type intersection(Type type) { if (this == tError || type == tError) @@ -372,6 +531,8 @@ public class Type { return type; if (type == tUnknown || this == type) return this; + /* We have two different singleton sets now. + */ if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_TYPES) != 0) GlobalOptions.err.println("intersecting "+ this +" and "+ type + " to "); @@ -380,7 +541,9 @@ public class Type { /** * Checks if we need to cast to a middle type, before we can cast from - * fromType to this type. + * fromType to this type. For example it is impossible to cast a + * String to a StringBuffer, but if we cast to Object in between this + * is allowed (it doesn't make much sense though). * @return the middle type, or null if it is not necessary. */ public Type getCastHelper(Type fromType) { @@ -388,29 +551,35 @@ public class Type { } /** - * Checks if this type represents a valid type instead of a list - * of minimum types. + * Checks if this type represents a valid singleton type. */ public boolean isValidType() { return typecode <= TC_DOUBLE; } /** - * Checks if this type represents a class or an array of a class + * Checks if this is a class or array type (but not a null type). + * @XXX remove this? + * @return true if this is a class or array type. */ public boolean isClassType() { return false; } /** - * Check if this and <unknown -- type&rt; are not disjunct. - * @param type a simple type; this mustn't be a range type. - * @return true if this is the case. + * Check if this type set and the other type set are not disjunct. + * @param type the other type set. + * @return true if this they aren't disjunct. */ public boolean isOfType(Type type) { return this.intersection(type) != Type.tError; } + /** + * Generates the default name, that is the `natural' choice for + * local of this type. + * @return the default name of a local of this type. + */ public String getDefaultName() { switch (typecode) { case TC_LONG: @@ -424,6 +593,11 @@ public class Type { } } + /** + * Generates the default value, that is the initial value of a field + * of this type. + * @return the default value of a field of this type. + */ public Object getDefaultValue() { switch (typecode) { case TC_LONG: @@ -437,6 +611,11 @@ public class Type { } } + /** + * Returns the type signature of this type. You should only call + * this on singleton types. + * @return the type (or method) signature of this type. + */ public String getTypeSignature() { switch (typecode) { case TC_LONG: @@ -450,6 +629,11 @@ public class Type { } } + /** + * Returns the java.lang.Class representing this type. You should + * only call this on singleton types. + * @return the Class object representing this type. + */ public Class getTypeClass() throws ClassNotFoundException { switch (typecode) { case TC_LONG: @@ -463,6 +647,10 @@ public class Type { } } + /** + * Returns a string representation describing this type set. + * @return a string representation describing this type set. + */ public String toString() { switch (typecode) { case TC_LONG: