*** empty log message ***

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@49 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 27 years ago
parent 1339141e8e
commit 2d1648439c
  1. 341
      jode/jode/type/ClassInterfacesType.java

@ -35,41 +35,62 @@ import java.util.Stack;
* @author Jochen Hoenicke */ * @author Jochen Hoenicke */
public class ClassInterfacesType extends MyType { public class ClassInterfacesType extends MyType {
ClassDeclaration clazz; Class clazz;
ClassDeclaration ifaces[]; Class ifaces[];
public final static Class cObject = new Object().getClass();
public ClassInterfacesType(Type clazzType) { public ClassInterfacesType(Type clazzType) {
super(104, "{"+clazzType.getTypeSignature()+"}"); super(104, "{"+clazzType.getTypeSignature()+"}");
ClassDeclaration cdecl =
new ClassDeclaration(clazzType.getClassName());
try { try {
if (cdecl.getClassDefinition(env).isInterface()) { Class cdecl =
clazz = new ClassDeclaration(Constants.idJavaLangObject); Class.forName(clazzType.getClassName().toString());
ifaces = new ClassDeclaration[1]; if (cdecl.isInterface()) {
clazz = cObject;
ifaces = new Class[1];
ifaces[0] = cdecl; ifaces[0] = cdecl;
} else { } else {
clazz = cdecl; clazz = cdecl;
ifaces = new ClassDeclaration[0]; ifaces = new Class[0];
} }
} catch (ClassNotFound ex) { } catch (ClassNotFoundException ex) {
throw new AssertError(ex.toString()); throw new AssertError(ex.toString());
} }
} }
public ClassInterfacesType(ClassDeclaration clazz, public ClassInterfacesType(Class clazz,
ClassDeclaration[] ifaces) { Class[] ifaces) {
super(104, "{}"); super(104, "{}");
StringBuffer sig = new StringBuffer("{"); StringBuffer sig = new StringBuffer("{");
if (clazz != null) if (clazz != null)
sig.append(clazz.getType().getTypeSignature()); sig.append("L").append(clazz.getName()).append(";");
for (int i=0;i < ifaces.length; i++) for (int i=0;i < ifaces.length; i++)
sig.append(ifaces[i].getType().getTypeSignature()); sig.append("L").append(ifaces[i].getName()).append(";");
sig.append("}"); sig.append("}");
typeSig = sig.toString(); typeSig = sig.toString();
this.clazz = clazz; this.clazz = clazz;
this.ifaces = ifaces; this.ifaces = ifaces;
} }
public final static boolean superClassOf(Class parent, Class clazz) {
while (clazz != parent && clazz != null) {
clazz = clazz.getSuperclass();
}
return clazz == parent;
}
public final static boolean implementedBy(Class iface, Class clazz) {
while (clazz != iface && clazz != null) {
Class[] ifaces = clazz.getInterfaces();
for (int i=0; i< ifaces.length; i++) {
if (implementedBy(iface, ifaces[i]))
return true;
}
clazz = clazz.getSuperclass();
}
return clazz != null;
}
/** /**
* Checks if the given type range may be not empty. * Checks if the given type range may be not empty.
* This means, that bottom.clazz is extended by top.clazz * This means, that bottom.clazz is extended by top.clazz
@ -81,65 +102,55 @@ public class ClassInterfacesType extends MyType {
*/ */
public final static Type createRangeType(ClassInterfacesType bottom, public final static Type createRangeType(ClassInterfacesType bottom,
ClassInterfacesType top) { ClassInterfacesType top) {
try { if (bottom.clazz != null
if (bottom.clazz != null && bottom.clazz != cObject) {
&& bottom.clazz.getType() != tObject) { /* The searched type must be a class type.
/* The searched type must be a class type. */
*/ if (top.ifaces.length != 0
if (top.ifaces.length != 0 || !superClassOf(bottom.clazz,top.clazz))
|| !bottom.clazz.getClassDefinition(env). return tError;
superClassOf(env,top.clazz))
/* All interfaces must be implemented by top.clazz
*/
for (int i=0; i < bottom.ifaces.length; i++) {
if (!implementedBy(bottom.ifaces[i], top.clazz))
return tError; return tError;
/* All interfaces must be implemented by top.clazz
*/
for (int i=0; i < bottom.ifaces.length; i++) {
if (!bottom.ifaces[i].getClassDefinition(env).
implementedBy(env,top.clazz))
return tError;
} }
return new ClassRangeType return new ClassRangeType
(bottom, new ClassInterfacesType(top.clazz, (bottom, new ClassInterfacesType(top.clazz,
new ClassDeclaration[0])); new Class[0]));
} else {
/* Now bottom.clazz is null, find all top.class/interfaces } else {
* that implement all bottom.ifaces.
*/ /* Now bottom.clazz is null, find all top.class/interfaces
ClassDeclaration clazz = top.clazz; * that implement all bottom.ifaces.
if (clazz != null) { */
for (int i=0; i < bottom.ifaces.length; i++) { Class clazz = top.clazz;
ClassDefinition idef = if (clazz != null) {
bottom.ifaces[i].getClassDefinition(env); for (int i=0; i < bottom.ifaces.length; i++) {
if (!idef.implementedBy(env, clazz)) { if (!implementedBy(bottom.ifaces[i], clazz)) {
clazz = null; clazz = null;
break; break;
}
} }
} }
Vector ifaces = new Vector(); }
big_loop: Vector ifaces = new Vector();
for (int j=0; j < top.ifaces.length; j++) { big_loop:
for (int i=0; i < bottom.ifaces.length; i++) { for (int j=0; j < top.ifaces.length; j++) {
ClassDefinition idef = for (int i=0; i < bottom.ifaces.length; i++) {
bottom.ifaces[i].getClassDefinition(env); if (!implementedBy(bottom.ifaces[i], top.ifaces[j]))
if (!idef.implementedBy(env, top.ifaces[j])) continue big_loop;
continue big_loop;
}
ifaces.addElement(top.ifaces[j]);
} }
ClassDeclaration[] ifaceArray = ifaces.addElement(top.ifaces[j]);
new ClassDeclaration[ifaces.size()]; }
Class[] ifaceArray =
new Class[ifaces.size()];
ifaces.copyInto(ifaceArray); ifaces.copyInto(ifaceArray);
return new ClassRangeType return new ClassRangeType
(bottom, new ClassInterfacesType(clazz, ifaceArray)); (bottom, new ClassInterfacesType(clazz, ifaceArray));
} }
} catch (ClassNotFound ex) {
return tError;
}
} }
/** /**
* Returns the specialized type of t1 and t2. * Returns the specialized type of t1 and t2.
* We have two classes and multiple interfaces. The result * We have two classes and multiple interfaces. The result
@ -149,77 +160,68 @@ public class ClassInterfacesType extends MyType {
public static Type getSpecializedType(ClassInterfacesType t1, public static Type getSpecializedType(ClassInterfacesType t1,
ClassInterfacesType t2) { ClassInterfacesType t2) {
ClassDeclaration clazz = null; Class clazz = null;
Vector ifaces = new Vector(); Vector ifaces = new Vector();
/* First determine the clazz, one of the two classes must be a sub /* First determine the clazz, one of the two classes must be a sub
* class of the other or null. * class of the other or null.
*/ */
try {
if (t1.clazz == null)
clazz = t2.clazz;
else if (t2.clazz == null)
clazz = t1.clazz;
else if (t1.clazz.
getClassDefinition(env).superClassOf(env, t2.clazz))
clazz = t2.clazz;
else if (t2.clazz.
getClassDefinition(env).superClassOf(env, t1.clazz))
clazz = t1.clazz;
else
return tError;
/* The interfaces are simply the union of both interfaces set. if (t1.clazz == null)
* But we can simplify this, if an interface is implemented by clazz = t2.clazz;
* another or by the class, we can omit it. else if (t2.clazz == null)
*/ clazz = t1.clazz;
big_loop_t1: else if (superClassOf(t1.clazz, t2.clazz))
for (int i=0; i< t1.ifaces.length; i++) { clazz = t2.clazz;
ClassDeclaration iface = t1.ifaces[i]; else if (superClassOf(t2.clazz, t1.clazz))
ClassDefinition idef = iface.getClassDefinition(env); clazz = t1.clazz;
if (clazz != null && idef.implementedBy(env, clazz)) { else
return tError;
/* The interfaces are simply the union of both interfaces set.
* But we can simplify this, if an interface is implemented by
* another or by the class, we can omit it.
*/
big_loop_t1:
for (int i=0; i< t1.ifaces.length; i++) {
Class iface = t1.ifaces[i];
if (clazz != null && implementedBy(iface, clazz)) {
continue big_loop_t1;
}
for (int j=0; j<t2.ifaces.length; j++) {
if (implementedBy(iface, t2.ifaces[j])) {
continue big_loop_t1; continue big_loop_t1;
} }
for (int j=0; j<t2.ifaces.length; j++) { }
if (idef.implementedBy(env, t2.ifaces[j])) {
continue big_loop_t1;
}
}
/* This interface is not implemented by any of the other /* This interface is not implemented by any of the other
* ifaces. Add it to the interfaces vector. * ifaces. Add it to the interfaces vector.
*/ */
ifaces.addElement(iface); ifaces.addElement(iface);
}
big_loop_t2:
for (int i=0; i< t2.ifaces.length; i++) {
Class iface = t2.ifaces[i];
if (clazz != null && implementedBy(iface, clazz)) {
continue big_loop_t2;
} }
big_loop_t2: for (int j=0; j<ifaces.size(); j++) {
for (int i=0; i< t2.ifaces.length; i++) { if (implementedBy(iface, (Class) ifaces.elementAt(j))) {
ClassDeclaration iface = t2.ifaces[i];
ClassDefinition idef = iface.getClassDefinition(env);
if (clazz != null && idef.implementedBy(env, clazz)) {
continue big_loop_t2; continue big_loop_t2;
} }
for (int j=0; j<ifaces.size(); j++) {
if (idef.implementedBy
(env, (ClassDeclaration) ifaces.elementAt(j))) {
continue big_loop_t2;
}
}
/* This interface is not implemented by any of the other
* ifaces. Add it to the interfaces vector.
*/
ifaces.addElement(iface);
} }
if (clazz.getType() == tObject && ifaces.size() > 0)
/* Every interface implies tObject, so remove it */
clazz = null;
} catch (ClassNotFound ex) {
return tError;
}
ClassDeclaration[] ifaceArray = new ClassDeclaration[ifaces.size()]; /* This interface is not implemented by any of the other
* ifaces. Add it to the interfaces vector.
*/
ifaces.addElement(iface);
}
if (clazz == cObject && ifaces.size() > 0)
/* Every interface implies tObject, so remove it */
clazz = null;
Class[] ifaceArray = new Class[ifaces.size()];
ifaces.copyInto(ifaceArray); ifaces.copyInto(ifaceArray);
return new ClassInterfacesType(clazz, ifaceArray); return new ClassInterfacesType(clazz, ifaceArray);
} }
@ -234,81 +236,77 @@ public class ClassInterfacesType extends MyType {
public static Type getGeneralizedType(ClassInterfacesType t1, public static Type getGeneralizedType(ClassInterfacesType t1,
ClassInterfacesType t2) { ClassInterfacesType t2) {
ClassDeclaration clazz; Class clazz;
Vector ifaces = new Vector(); Vector ifaces = new Vector();
try { /* First the easy part, determine the clazz */
/* First the easy part, determine the clazz */ if (t1.clazz == null)
if (t1.clazz == null) clazz = t2.clazz;
clazz = t2.clazz; else if (t2.clazz == null)
else if (t2.clazz == null) clazz = t1.clazz;
clazz = t1.clazz; else {
else { clazz = t1.clazz;
clazz = t1.clazz;
while(clazz != null) { while(clazz != null) {
ClassDefinition cdef = clazz.getClassDefinition(env); if (superClassOf(clazz, t2.clazz))
if (cdef.superClassOf(env, t2.clazz)) break;
break; clazz = clazz.getSuperclass();
clazz = cdef.getSuperClass(env);
}
if (clazz.getType() == tObject)
clazz = null;
} }
if (clazz == cObject)
clazz = null;
}
/* Now the more complicated part: find all interfaces, that are /* Now the more complicated part: find all interfaces, that are
* implemented by one interface or class in each group. * implemented by one interface or class in each group.
* *
* First get all interfaces of t1.clazz and t1.ifaces. * First get all interfaces of t1.clazz and t1.ifaces.
*/ */
Stack allIfaces = new Stack(); Stack allIfaces = new Stack();
if (t1.clazz != null) { if (t1.clazz != null) {
ClassDeclaration clazzIfaces[] = Class c = t1.clazz;
t1.clazz.getClassDefinition(env).getInterfaces(); while (clazz != c) {
Class clazzIfaces[] = c.getInterfaces();
for (int i=0; i<clazzIfaces.length; i++) for (int i=0; i<clazzIfaces.length; i++)
allIfaces.push(clazzIfaces[i]); allIfaces.push(clazzIfaces[i]);
c = c.getSuperclass();
} }
for (int i=0; i<t1.ifaces.length; i++) }
for (int i=0; i<t1.ifaces.length; i++)
allIfaces.push(t1.ifaces[i]); allIfaces.push(t1.ifaces[i]);
/* Now consider each interface. If any clazz or interface /* Now consider each interface. If any clazz or interface
* in t2 implements it, add it to the ifaces vector. * in t2 implements it, add it to the ifaces vector.
* Otherwise consider all sub interfaces. * Otherwise consider all sub interfaces.
*/ */
iface_loop: iface_loop:
while (!allIfaces.isEmpty()) { while (!allIfaces.isEmpty()) {
ClassDeclaration iface = (ClassDeclaration) allIfaces.pop(); Class iface = (Class) allIfaces.pop();
ClassDefinition idef = iface.getClassDefinition(env); if (clazz != null && implementedBy(iface, clazz))
if (clazz != null && idef.implementedBy(env, clazz)) /* We can skip this, as clazz does already imply it.
/* We can skip this, as clazz does already imply it. */
*/ continue iface_loop;
continue iface_loop;
if (t2.clazz != null && idef.implementedBy(env, t2.clazz)) { if (t2.clazz != null && implementedBy(iface, t2.clazz)) {
ifaces.addElement(iface);
continue iface_loop;
}
for (int i=0; i<t2.ifaces.length; i++) {
if (implementedBy(iface, t2.ifaces[i])) {
ifaces.addElement(iface); ifaces.addElement(iface);
continue iface_loop; continue iface_loop;
} }
for (int i=0; i<t2.ifaces.length; i++) {
if (idef.implementedBy(env, t2.ifaces[i])) {
ifaces.addElement(iface);
continue iface_loop;
}
}
/* This interface is not implemented by any of the other
* ifaces. Try its parent interfaces now.
*/
ClassDeclaration clazzIfaces[] = idef.getInterfaces();
for (int i=0; i<clazzIfaces.length; i++)
allIfaces.push(clazzIfaces[i]);
} }
} catch (ClassNotFound ex) {
return tError;
}
ClassDeclaration[] ifaceArray = new ClassDeclaration[ifaces.size()]; /* This interface is not implemented by any of the other
* ifaces. Try its parent interfaces now.
*/
Class clazzIfaces[] = iface.getInterfaces();
for (int i=0; i<clazzIfaces.length; i++)
allIfaces.push(clazzIfaces[i]);
}
Class[] ifaceArray = new Class[ifaces.size()];
ifaces.copyInto(ifaceArray); ifaces.copyInto(ifaceArray);
return new ClassInterfacesType(clazz, ifaceArray); return new ClassInterfacesType(clazz, ifaceArray);
} }
@ -329,12 +327,11 @@ public class ClassInterfacesType extends MyType {
return sb.append("}").append(string).toString(); return sb.append("}").append(string).toString();
} else { } else {
if (clazz != null) if (clazz != null)
return clazz.getType().typeString(string, flag1, flag2); return clazz.toString() + string;
else if (ifaces.length > 0) else if (ifaces.length > 0)
return ifaces[0].getType().typeString(string, flag1, flag2); return ifaces[0].toString() + string;
else else
return tError.typeString(string,flag1,flag2); return tError.toString() + string;
} }
} }
} }

Loading…
Cancel
Save