made new abstract class ReferenceType

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@417 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent badfd86844
commit af995a7761
  1. 46
      jode/jode/type/ArrayType.java
  2. 92
      jode/jode/type/ClassInterfacesType.java
  3. 54
      jode/jode/type/NullType.java
  4. 46
      jode/jode/type/RangeType.java

@ -25,7 +25,7 @@ import java.util.Vector;
* *
* @author Jochen Hoenicke * @author Jochen Hoenicke
*/ */
public class ArrayType extends ClassInterfacesType { public class ArrayType extends ReferenceType {
// The interfaces that an array implements: // The interfaces that an array implements:
final static ClassInfo[] arrayIfaces = { final static ClassInfo[] arrayIfaces = {
// Make sure to list all interfaces, even if some interface // Make sure to list all interfaces, even if some interface
@ -37,7 +37,7 @@ public class ArrayType extends ClassInterfacesType {
Type elementType; Type elementType;
public ArrayType(Type elementType) { public ArrayType(Type elementType) {
super(null, arrayIfaces); super(TC_ARRAY);
typecode = TC_ARRAY; typecode = TC_ARRAY;
this.elementType = elementType; this.elementType = elementType;
} }
@ -47,22 +47,14 @@ public class ArrayType extends ClassInterfacesType {
} }
public Type getSuperType() { public Type getSuperType() {
return tRange(tObject, (ClassInterfacesType) return tRange(tObject,
tArray(elementType.getSuperType())); (ReferenceType) tArray(elementType.getSuperType()));
} }
public Type getSubType() { public Type getSubType() {
return tArray(elementType.getSubType()); return tArray(elementType.getSubType());
} }
// public Type getBottom() {
// return tArray(elementType.getBottom());
// }
// public Type getTop() {
// return tArray(elementType.getTop());
// }
public Type getHint() { public Type getHint() {
return tArray(elementType.getHint()); return tArray(elementType.getHint());
} }
@ -72,7 +64,7 @@ public class ArrayType extends ClassInterfacesType {
* @param bottomType the start point of the range * @param bottomType the start point of the range
* @return the range type, or tError if not possible. * @return the range type, or tError if not possible.
*/ */
public Type createRangeType(ClassInterfacesType bottom) { public Type createRangeType(ReferenceType bottom) {
/* /*
* tArray(y), tArray(x) -> tArray( y.intersection(x) ) * tArray(y), tArray(x) -> tArray( y.intersection(x) )
* obj , tArray(x) -> <obj, tArray(x)> * obj , tArray(x) -> <obj, tArray(x)>
@ -83,9 +75,10 @@ public class ArrayType extends ClassInterfacesType {
(((ArrayType)bottom).elementType)); (((ArrayType)bottom).elementType));
if (bottom.getTypeCode() == TC_CLASS) { if (bottom.getTypeCode() == TC_CLASS) {
if (bottom.clazz == null ClassInterfacesType bottomCIT = (ClassInterfacesType)bottom;
&& implementsAllIfaces(bottom.ifaces)) if (bottomCIT.clazz == null
return tRange(bottom, this); && implementsAllIfaces(null, arrayIfaces, bottomCIT.ifaces))
return tRange(bottomCIT, this);
} }
return tError; return tError;
} }
@ -113,7 +106,7 @@ public class ArrayType extends ClassInterfacesType {
if (type.getTypeCode() == TC_CLASS) { if (type.getTypeCode() == TC_CLASS) {
ClassInterfacesType other = (ClassInterfacesType) type; ClassInterfacesType other = (ClassInterfacesType) type;
if (other.clazz == null if (other.clazz == null
&& implementsAllIfaces(other.ifaces)) && implementsAllIfaces(null, arrayIfaces, other.ifaces))
return this; return this;
} }
return tError; return tError;
@ -126,7 +119,7 @@ public class ArrayType extends ClassInterfacesType {
*/ */
public Type getGeneralizedType(Type type) { public Type getGeneralizedType(Type type) {
/* tArray(x), tNull -> tArray(x) /* tArray(x), tNull -> tArray(x)
* tArray(x), tClass(y) -> tObject, ifaces of tArray and tClass * tArray(x), tClass(y) -> common ifaces of tArray and tClass
* tArray(x), tArray(y) -> tArray(x.intersection(y)) * tArray(x), tArray(y) -> tArray(x.intersection(y))
* tArray(x), other -> tError * tArray(x), other -> tError
*/ */
@ -140,9 +133,10 @@ public class ArrayType extends ClassInterfacesType {
(((ArrayType)type).elementType)); (((ArrayType)type).elementType));
if (type.getTypeCode() == TC_CLASS) { if (type.getTypeCode() == TC_CLASS) {
ClassInterfacesType other = (ClassInterfacesType) type; ClassInterfacesType other = (ClassInterfacesType) type;
if (other.implementsAllIfaces(ifaces)) if (implementsAllIfaces(other.clazz, other.ifaces, arrayIfaces))
return ClassInterfacesType.create(null, ifaces); return ClassInterfacesType.create(null, arrayIfaces);
if (other.clazz == null && implementsAllIfaces(other.ifaces)) if (other.clazz == null
&& implementsAllIfaces(null, arrayIfaces, other.ifaces))
return other; return other;
/* Now the more complicated part: find all interfaces, that are /* Now the more complicated part: find all interfaces, that are
@ -152,18 +146,18 @@ public class ArrayType extends ClassInterfacesType {
*/ */
Vector newIfaces = new Vector(); Vector newIfaces = new Vector();
iface_loop: iface_loop:
for (int i=0; i < ifaces.length; i++) { for (int i=0; i < arrayIfaces.length; i++) {
/* Now consider each array interface. If any clazz or /* Now consider each array interface. If any clazz or
* interface in other implements it, add it to the * interface in other implements it, add it to the
* newIfaces vector. */ * newIfaces vector. */
if (other.clazz != null if (other.clazz != null
&& ifaces[i].implementedBy(other.clazz)) { && arrayIfaces[i].implementedBy(other.clazz)) {
newIfaces.addElement(ifaces[i]); newIfaces.addElement(arrayIfaces[i]);
continue iface_loop; continue iface_loop;
} }
for (int j=0; j<other.ifaces.length; j++) { for (int j=0; j<other.ifaces.length; j++) {
if (ifaces[i].implementedBy(other.ifaces[j])) { if (arrayIfaces[i].implementedBy(other.ifaces[j])) {
newIfaces.addElement(ifaces[i]); newIfaces.addElement(arrayIfaces[i]);
continue iface_loop; continue iface_loop;
} }
} }

@ -33,7 +33,7 @@ import java.util.Stack;
* the searched type. * the searched type.
* *
* @author Jochen Hoenicke */ * @author Jochen Hoenicke */
public class ClassInterfacesType extends Type { public class ClassInterfacesType extends ReferenceType {
ClassInfo clazz; ClassInfo clazz;
ClassInfo ifaces[]; ClassInfo ifaces[];
@ -73,14 +73,6 @@ public class ClassInterfacesType extends Type {
this.ifaces = ifaces; this.ifaces = ifaces;
} }
public Type getSuperType() {
return (this == tObject) ? tObject : tRange(tObject, this);
}
public Type getSubType() {
return tRange(this, tNull);
}
static ClassInterfacesType create(ClassInfo clazz, ClassInfo[] ifaces) { static ClassInterfacesType create(ClassInfo clazz, ClassInfo[] ifaces) {
/* Make sure that every {java.lang.Object} equals tObject */ /* Make sure that every {java.lang.Object} equals tObject */
if (ifaces.length == 0 && clazz == null) if (ifaces.length == 0 && clazz == null)
@ -107,14 +99,15 @@ public class ClassInterfacesType extends Type {
* @param bottom the start point of the range * @param bottom the start point of the range
* @return the range type, or tError if range is empty. * @return the range type, or tError if range is empty.
*/ */
public Type createRangeType(ClassInterfacesType bottom) { public Type createRangeType(ReferenceType bottomType) {
if (bottomType.typecode != TC_CLASS)
return tError;
ClassInterfacesType bottom = (ClassInterfacesType) bottomType;
if (bottom == tObject) if (bottomType == tObject)
return (this == tObject) ? tObject : tRange(tObject, this); return (this == tObject) ? tObject : tRange(tObject, this);
if (bottom.typecode != TC_CLASS)
return tError;
if (bottom.clazz != null) { if (bottom.clazz != null) {
/* The searched type must be a class type. /* The searched type must be a class type.
*/ */
@ -186,21 +179,6 @@ public class ClassInterfacesType extends Type {
return tRange(bottom, create(clazz, ifaces)); return tRange(bottom, create(clazz, ifaces));
} }
} }
protected boolean implementsAllIfaces(ClassInfo[] otherIfaces) {
big:
for (int i=0; i < otherIfaces.length; i++) {
ClassInfo iface = otherIfaces[i];
if (clazz != null && iface.implementedBy(clazz))
continue big;
for (int j=0; j < this.ifaces.length; j++) {
if (iface.implementedBy(ifaces[j]))
continue big;
}
return false;
}
return true;
}
/** /**
* Returns the specialized type of this and type. * Returns the specialized type of this and type.
@ -244,10 +222,11 @@ public class ClassInterfacesType extends Type {
* class where at one intersection this doesn't succeed) * class where at one intersection this doesn't succeed)
*/ */
if (clazz == this.clazz if (clazz == this.clazz
&& implementsAllIfaces(other.ifaces)) && implementsAllIfaces(this.clazz, this.ifaces, other.ifaces))
return this; return this;
else if (clazz == other.clazz else if (clazz == other.clazz
&& other.implementsAllIfaces(this.ifaces)) && implementsAllIfaces(other.clazz, other.ifaces,
this.ifaces))
return other; return other;
/* The interfaces are simply the union of both interfaces set. /* The interfaces are simply the union of both interfaces set.
@ -333,10 +312,10 @@ public class ClassInterfacesType extends Type {
} }
if (clazz == this.clazz if (clazz == this.clazz
&& other.implementsAllIfaces(this.ifaces)) && implementsAllIfaces(other.clazz, other.ifaces, this.ifaces))
return this; return this;
else if (clazz == other.clazz else if (clazz == other.clazz
&& this.implementsAllIfaces(other.ifaces)) && implementsAllIfaces(this.clazz, this.ifaces, other.ifaces))
return other; return other;
/* Now the more complicated part: find all interfaces, that are /* Now the more complicated part: find all interfaces, that are
@ -523,51 +502,4 @@ public class ClassInterfacesType extends Type {
} }
return false; return false;
} }
/**
* 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.
*/
public Type intersection(Type type) {
if (type == tError)
return type;
if (type == Type.tUnknown)
return this;
ClassInterfacesType top, bottom;
// if (type instanceof RangeType) {
// top = ((RangeType)type).getTop();
// bottom = ((RangeType)type).getBottom();
// } else if (type instanceof ClassInterfacesType) {
// top = bottom = (ClassInterfacesType) type;
// } else {
// Decompiler.err.println("intersecting "+ this +" and "+ type
// + " to <error>");
// if (Decompiler.isTypeDebugging)
// throw new AssertError("type error");
// return tError;
// }
Type newBottom = getSpecializedType(type);
Type newTop = getGeneralizedType(type);
Type result;
if (newTop.equals(newBottom))
result = newTop;
else if (newTop instanceof ClassInterfacesType
&& newBottom instanceof ClassInterfacesType)
result = ((ClassInterfacesType) newTop)
.createRangeType((ClassInterfacesType) newBottom);
else
result = tError;
if (result == tError) {
Decompiler.err.println("intersecting "+ this +" and "+ type
+ " to <" + newBottom + "," + newTop + ">"
+ " to <error>");
} else if (Decompiler.isTypeDebugging) {
Decompiler.err.println("intersecting "+ this +" and "+ type +
" to " + result);
}
return result;
}
} }

@ -1,11 +1,39 @@
/* ReferenceType Copyright (C) 1997-1998 Jochen Hoenicke.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
*/
package jode; package jode;
public class NullType extends ClassInterfacesType {
/**
* This class represents the NullType. The null type is special as it
* may only occur as top type in a range type. It represents the type
* of the null constant, which may be casted to any object. <br>
*
* Question: Should we replace tUObject = tRange(tObject, tNull) by tNull?
* Question2: if not, should null have type tNull?
*
* @author Jochen Hoenicke
*/
public class NullType extends ReferenceType {
public NullType() { public NullType() {
super(null, null); super(TC_NULL);
typecode = TC_NULL;
} }
public Type createRangeType(ClassInterfacesType bottomType) { public Type createRangeType(ReferenceType bottomType) {
return tRange(bottomType, this); return tRange(bottomType, this);
} }
@ -14,12 +42,14 @@ public class NullType extends ClassInterfacesType {
* classes and multiple interfaces. The result should be the * classes and multiple interfaces. The result should be the
* object that is the the super class of both objects and all * object that is the the super class of both objects and all
* interfaces, that one class or interface of each type * interfaces, that one class or interface of each type
* implements. */ * implements.
*/
public Type getGeneralizedType(Type type) { public Type getGeneralizedType(Type type) {
if (type.typecode == TC_RANGE) if (type.typecode == TC_RANGE)
type = ((RangeType) type).getTop(); type = ((RangeType) type).getTop();
return type; return type;
} }
/** /**
* Returns the specialized type of this and type. * Returns the specialized type of this and type.
* We have two classes and multiple interfaces. The result * We have two classes and multiple interfaces. The result
@ -32,24 +62,10 @@ public class NullType extends ClassInterfacesType {
return type; return type;
} }
/**
* Marks this type as used, so that the class is imported.
*/
public void useType() {
}
public String toString() { public String toString() {
return "/*NULL*/" + env.classString("java.lang.Object"); return "/*NULL*/" + env.classString("java.lang.Object");
} }
public boolean equals(Object o) {
return o == this;
}
public Type getHint() {
return tNull;
}
/** /**
* Intersect this type with another type and return the new type. * Intersect this type with another type and return the new type.
* @param type the other type. * @param type the other type.

@ -36,37 +36,22 @@ import java.util.Hashtable;
* @date 98/08/06 * @date 98/08/06
*/ */
public class RangeType extends Type { public class RangeType extends Type {
final ClassInterfacesType bottomType; final ReferenceType bottomType;
final ClassInterfacesType topType; final ReferenceType topType;
// final Type hintType; public RangeType(ReferenceType bottomType,
ReferenceType topType) {
// public RangeType(Type bottomType, Type topType, Type hintType) {
// super(TC_RANGE);
// if (bottom.typecode == TC_RANGE
// || top.typecode == TC_RANGE)
// throw new AssertError("tRange("+bottom+","+top+")");
// if (top.typecode == TC_UNKNOWN)
// throw new AssertError("tRange(tUnknown, "+top+")");
// this.bottomType = bottomType;
// this.topType = topType;
// this.hintType = hintType;
// }
public RangeType(ClassInterfacesType bottomType,
ClassInterfacesType topType) {
super(TC_RANGE); super(TC_RANGE);
if (bottomType == tNull) if (bottomType == tNull)
throw new jode.AssertError("bottom is NULL"); throw new jode.AssertError("bottom is NULL");
this.bottomType = bottomType; this.bottomType = bottomType;
this.topType = topType; this.topType = topType;
// this.hintType = bottomType.isValidType() ? bottomType : topType;
} }
public ClassInterfacesType getBottom() { public ReferenceType getBottom() {
return bottomType; return bottomType;
} }
public ClassInterfacesType getTop() { public ReferenceType getTop() {
return topType; return topType;
} }
@ -88,7 +73,7 @@ public class RangeType extends Type {
// * @param bottomType the start point of the range // * @param bottomType the start point of the range
// * @return the range type, or tError if not possible. // * @return the range type, or tError if not possible.
// */ // */
// public ClassInterfacesType createRangeType(ClassInterfacesType bottomType) { // public ReferenceType createRangeType(ReferenceType bottomType) {
// throw new AssertError("createRangeType called on RangeType"); // throw new AssertError("createRangeType called on RangeType");
// } // }
@ -97,7 +82,7 @@ public class RangeType extends Type {
// * @param type the other type. // * @param type the other type.
// * @return the common sub type. // * @return the common sub type.
// */ // */
// public ClassInterfacesType getSpecializedType(ClassInterfacesType type) { // public ReferenceType getSpecializedType(ReferenceType type) {
// throw new AssertError("getSpecializedType called on RangeType"); // throw new AssertError("getSpecializedType called on RangeType");
// } // }
@ -178,21 +163,18 @@ public class RangeType extends Type {
bottom = bottomType.getSpecializedType(type); bottom = bottomType.getSpecializedType(type);
if (top.equals(bottom)) if (top.equals(bottom))
result = top; result = top;
else if (top instanceof ClassInterfacesType else if (top instanceof ReferenceType
&& bottom instanceof ClassInterfacesType) && bottom instanceof ReferenceType)
result = ((ClassInterfacesType)top) result = ((ReferenceType)top)
.createRangeType((ClassInterfacesType)bottom); .createRangeType((ReferenceType)bottom);
else else
result = tError; result = tError;
if (result == tError) { if (Decompiler.isTypeDebugging) {
Decompiler.err.println("intersecting "+ this +" and "+ type
+ " to <" + bottom + "," + top + ">"
+ " to <error>");
} else if (Decompiler.isTypeDebugging) {
Decompiler.err.println("intersecting "+ this +" and "+ type + Decompiler.err.println("intersecting "+ this +" and "+ type +
" to " + result); " to " + result);
} }
return result; return result;
} }
} }

Loading…
Cancel
Save