/* * MyType (c) 1998 Jochen Hoenicke * * You may distribute under the terms of the GNU General Public License. * * IN NO EVENT SHALL JOCHEN HOENICKE BE LIABLE TO ANY PARTY FOR DIRECT, * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF JOCHEN HOENICKE * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * JOCHEN HOENICKE SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" * BASIS, AND JOCHEN HOENICKE HAS NO OBLIGATION TO PROVIDE MAINTENANCE, * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * $Id$ */ package jode; import sun.tools.java.Constants; import sun.tools.java.Type; import sun.tools.java.Identifier; import java.util.Hashtable; /** * This is my own type class. It differs from sun.tools.java.Type, in * that it maintains a type range. This type range may be implicit or * explicit.
* * The type tInt (which is the same as Type.tInt) is a good example * for the implicit range <tInt -- tBoolean>. Most other * standard types stand for the range consisting only of themselve. * The explicit form is the class range type
* * The main operation on a type range is the intersection. To do this * on class ranges we need two more operations: specialization and * generalization.
* * specialization chooses the startpoint of two intervals which * lies in the open range <sp -- null>, where sp is the startpoint * of the other interval, or returns tError on failure.
* * generalization chooses the endpoint of two intervals which lies in * the open range <null -- ep>, where ep is the endpoint of * the other interval, or returns tError on failure.
*/
public class MyType extends Type {
static Hashtable superclasses = new Hashtable();
protected static JodeEnvironment env;
public static final Type tStringBuffer =
Type.tClass(idJavaLangStringBuffer);
public static final Type tUnknown = new ClassRangeType(null, null);
public static final Type tUInt = tInt;
public static final Type tUIndex = tInt;
public static final Type tUObject = new ClassRangeType(tObject, null);
public static Type tSuperType(Type type) {
int typeCode = type.getTypeCode();
if (typeCode == 9 || typeCode == 10 || typeCode == 103)
return new ClassRangeType(tObject, type);
else
return type;
}
public static Type tSubType(Type type) {
int typeCode = type.getTypeCode();
if (typeCode == 9 || typeCode == 10 || typeCode == 103)
return new ClassRangeType(type, null);
else
return type;
}
public static Type tClassOrArray(Identifier ident) {
if (ident.toString().charAt(0) == '[')
return MyType.tType(ident.toString());
else
return MyType.tClass(ident);
}
public static void setEnvironment(JodeEnvironment e) {
env = e;
}
protected MyType(int i, String str) {
super (i, str);
}
public int stackSize()
{
return 1;
}
public String typeString(String var, boolean flag1, boolean flag2)
{
String typeStr;
switch (typeCode) {
case 100: typeStr="unknown"; break;
default:
throw new RuntimeException("Wrong typeCode "+typeCode);
}
if (var.length() > 0)
return typeStr+" "+var;
return typeStr;
}
/**
* Find the intersection of two types
* @param t1 the first type.
* @param t2 the second type.
* @return the intersection, or tError, if a type conflict happens.
*/
public static Type intersection(Type t1, Type t2) {
// System.err.println("intersecting "+ t1 +" and "+ t2);
/* Trivial cases first.
*/
if (t1 == tError || t2 == tError) {
System.err.println("intersecting "+ t1 +" and "+ t2 +
" to