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

@ -33,7 +33,7 @@ import java.util.Stack;
* the searched type.
*
* @author Jochen Hoenicke */
public class ClassInterfacesType extends Type {
public class ClassInterfacesType extends ReferenceType {
ClassInfo clazz;
ClassInfo ifaces[];
@ -73,14 +73,6 @@ public class ClassInterfacesType extends Type {
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) {
/* Make sure that every {java.lang.Object} equals tObject */
if (ifaces.length == 0 && clazz == null)
@ -107,14 +99,15 @@ public class ClassInterfacesType extends Type {
* @param bottom the start point of the range
* @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);
if (bottom.typecode != TC_CLASS)
return tError;
if (bottom.clazz != null) {
/* The searched type must be a class type.
*/
@ -186,21 +179,6 @@ public class ClassInterfacesType extends Type {
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.
@ -244,10 +222,11 @@ public class ClassInterfacesType extends Type {
* class where at one intersection this doesn't succeed)
*/
if (clazz == this.clazz
&& implementsAllIfaces(other.ifaces))
&& implementsAllIfaces(this.clazz, this.ifaces, other.ifaces))
return this;
else if (clazz == other.clazz
&& other.implementsAllIfaces(this.ifaces))
&& implementsAllIfaces(other.clazz, other.ifaces,
this.ifaces))
return other;
/* The interfaces are simply the union of both interfaces set.
@ -333,10 +312,10 @@ public class ClassInterfacesType extends Type {
}
if (clazz == this.clazz
&& other.implementsAllIfaces(this.ifaces))
&& implementsAllIfaces(other.clazz, other.ifaces, this.ifaces))
return this;
else if (clazz == other.clazz
&& this.implementsAllIfaces(other.ifaces))
&& implementsAllIfaces(this.clazz, this.ifaces, other.ifaces))
return other;
/* Now the more complicated part: find all interfaces, that are
@ -523,51 +502,4 @@ public class ClassInterfacesType extends Type {
}
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;
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() {
super(null, null);
typecode = TC_NULL;
super(TC_NULL);
}
public Type createRangeType(ClassInterfacesType bottomType) {
public Type createRangeType(ReferenceType bottomType) {
return tRange(bottomType, this);
}
@ -14,12 +42,14 @@ public class NullType extends ClassInterfacesType {
* classes and multiple interfaces. The result should be the
* object that is the the super class of both objects and all
* interfaces, that one class or interface of each type
* implements. */
* implements.
*/
public Type getGeneralizedType(Type type) {
if (type.typecode == TC_RANGE)
type = ((RangeType) type).getTop();
return type;
}
/**
* Returns the specialized type of this and type.
* We have two classes and multiple interfaces. The result
@ -32,24 +62,10 @@ public class NullType extends ClassInterfacesType {
return type;
}
/**
* Marks this type as used, so that the class is imported.
*/
public void useType() {
}
public String toString() {
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.
* @param type the other type.

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

Loading…
Cancel
Save