Commit 4b2b571e authored by Lubomir Bulej's avatar Lubomir Bulej

Simplify implementation of the ShadowClass hierarchy. Use ASM Type in the

abstract ShadowClass to derive answers to most queries, leaving the subclasses
to only deal with to deal with the specifics. 
parent 336caab5
package ch.usi.dag.dislreserver.shadow;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import org.objectweb.asm.Type;
import ch.usi.dag.dislreserver.DiSLREServerFatalException;
final class ArrayShadowClass extends ShadowClass {
private final Type __type;
private final ShadowClass __superClass;
private final ShadowClass __componentClass;
//
ArrayShadowClass (
......@@ -23,90 +19,75 @@ final class ArrayShadowClass extends ShadowClass {
final ShadowObject classLoader, final ShadowClass superClass,
final ShadowClass componentClass
) {
super (netReference, classLoader);
super (netReference, type, classLoader);
__type = type;
__superClass = superClass;
__componentClass = componentClass;
}
//
@Override
public boolean isArray () {
return true;
}
public int getArrayDimensions () {
return __type.getDimensions ();
public int getDimensionCount () {
return _type ().getDimensions ();
}
@Override
public ShadowClass getComponentType () {
// return arrayComponentClass;
throw new DiSLREServerFatalException ("ArrayShadowClass.getComponentType not implemented");
}
@Override
public boolean isInstance (final ShadowObject obj) {
return equals (obj.getShadowClass ());
}
@Override
public boolean isAssignableFrom (final ShadowClass klass) {
return
equals (klass)
||
(
(klass instanceof ArrayShadowClass)
&&
__componentClass.isAssignableFrom (klass.getComponentType ())
);
}
if (__componentClass != null) {
return __componentClass;
}
@Override
public boolean isInterface () {
return false;
throw new UnsupportedOperationException ("not yet implemented");
}
//
/**
* @see Class#isInstance(Object)
*/
@Override
public boolean isPrimitive () {
return false;
public boolean isInstance (final ShadowObject object) {
return equals (object.getShadowClass ());
}
/**
* @see Class#isAssignableFrom(Class)
*/
@Override
public boolean isAnnotation () {
return false;
}
public boolean isAssignableFrom (final ShadowClass other) {
if (this.equals (other)) {
return true;
}
@Override
public boolean isSynthetic () {
return false;
}
if (other instanceof ArrayShadowClass) {
// This is needed until we properly implement componentType.
if (__componentClass == null) {
throw new UnsupportedOperationException ("component type comparison not implemented yet");
}
return __componentClass.isAssignableFrom (other.getComponentType ());
}
@Override
public boolean isEnum () {
return false;
}
//
@Override
public String getName () {
return __type.getDescriptor ().replace ('/', '.');
public int getModifiers () {
// Array classes are ABSTRACT and FINAL, privacy depends on the
// privacy of the component type. Until we get valid component type,
// we will make the array classes public.
return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC;
}
//
@Override
public String getCanonicalName () {
return __type.getClassName ();
public ShadowClass getSuperclass () {
return __superClass;
}
......@@ -115,16 +96,11 @@ final class ArrayShadowClass extends ShadowClass {
return new String [] { "java.lang.Cloneable", "java.io.Serializable" };
}
//
@Override
public String getPackage () {
return null;
}
@Override
public ShadowClass getSuperclass () {
return __superClass;
public FieldInfo getField (final String fieldName) throws NoSuchFieldException {
throw new NoSuchFieldException (getCanonicalName () + "." + fieldName);
}
......@@ -133,18 +109,21 @@ final class ArrayShadowClass extends ShadowClass {
return new FieldInfo [0];
}
//
@Override
public FieldInfo getField (final String fieldName) throws NoSuchFieldException {
throw new NoSuchFieldException (__type.getClassName () + "." + fieldName);
public FieldInfo getDeclaredField (final String fieldName)
throws NoSuchFieldException {
throw new NoSuchFieldException (getCanonicalName () + "." + fieldName);
}
@Override
public MethodInfo [] getMethods () {
return getSuperclass ().getMethods ();
public FieldInfo [] getDeclaredFields () {
return new FieldInfo [0];
}
//
@Override
public MethodInfo getMethod (final String methodName, final String [] argumentNames)
......@@ -159,27 +138,25 @@ final class ArrayShadowClass extends ShadowClass {
}
throw new NoSuchMethodException (
__type.getClassName () + "." + methodName + argumentNamesToString (argumentNames)
getCanonicalName () + "." + methodName + _descriptorsToString (argumentNames)
);
}
@Override
public String [] getDeclaredClasses () {
return new String [0];
}
@Override
public FieldInfo [] getDeclaredFields () {
return new FieldInfo [0];
public MethodInfo [] getMethods () {
return getSuperclass ().getMethods ();
}
//
@Override
public FieldInfo getDeclaredField (final String fieldName)
throws NoSuchFieldException {
throw new NoSuchFieldException (__type.getClassName () + "." + fieldName);
public MethodInfo getDeclaredMethod (final String methodName,
final String [] argumentNames)
throws NoSuchMethodException {
throw new NoSuchMethodException (
getCanonicalName () + "." + methodName + _descriptorsToString (argumentNames)
);
}
......@@ -188,14 +165,11 @@ final class ArrayShadowClass extends ShadowClass {
return new MethodInfo [0];
}
//
@Override
public MethodInfo getDeclaredMethod (final String methodName,
final String [] argumentNames)
throws NoSuchMethodException {
throw new NoSuchMethodException (
__type.getClassName () + "." + methodName + argumentNamesToString (argumentNames)
);
public String [] getDeclaredClasses () {
return new String [0];
}
}
......@@ -24,17 +24,16 @@ final class ObjectShadowClass extends ShadowClass {
private ClassNode __classNode;
private int __access;
private String __name;
//
ObjectShadowClass (
final long netReference, final Type type,
final ShadowObject classLoader, final ShadowClass superClass,
final byte [] classCode
) {
super (netReference, classLoader);
super (netReference, type, classLoader);
__superClass = superClass;
if (classCode == null || classCode.length == 0) {
......@@ -63,7 +62,6 @@ final class ObjectShadowClass extends ShadowClass {
__classNode = new ClassNode (Opcodes.ASM4);
classReader.accept (__classNode, ClassReader.SKIP_DEBUG | ClassReader.EXPAND_FRAMES);
__access = __classNode.access;
__name = __classNode.name.replace ('/', '.');
methods = new ArrayList <MethodInfo> (__classNode.methods.size ());
......@@ -105,80 +103,41 @@ final class ObjectShadowClass extends ShadowClass {
}
@Override
public boolean isArray () {
return false;
}
@Override
public ShadowClass getComponentType () {
return null;
}
//
@Override
public boolean isInstance (final ShadowObject obj) {
// return equals(obj.getSClass());
throw new DiSLREServerFatalException ("ShadowCommonClass.isInstance not implemented");
public boolean isInstance (final ShadowObject object) {
// return equals(obj.getShadowClass());
throw new UnsupportedOperationException ("not yet implemented");
}
@Override
public boolean isAssignableFrom (final ShadowClass klass) {
// while (klass != null) {
// if (klass.equals(this)) {
// return true;
// }
//
// if (klass.equals(this)) {
// return true;
// }
//
// klass = klass.getSuperclass();
// klass = klass.getSuperclass();
// }
//
// return false;
throw new DiSLREServerFatalException ("ShadowCommonClass.isAssignableFrom not implemented");
throw new UnsupportedOperationException ("not yet implemented");
}
//
@Override
public boolean isInterface () {
return (__access & Opcodes.ACC_INTERFACE) != 0;
public int getModifiers () {
return __classNode.access;
}
//
@Override
public boolean isPrimitive () {
return false;
}
@Override
public boolean isAnnotation () {
return (__access & Opcodes.ACC_ANNOTATION) != 0;
}
@Override
public boolean isSynthetic () {
return (__access & Opcodes.ACC_SYNTHETIC) != 0;
}
@Override
public boolean isEnum () {
return (__access & Opcodes.ACC_ENUM) != 0;
}
@Override
public String getName () {
return __name;
}
@Override
public String getCanonicalName () {
throw new DiSLREServerFatalException ("ShadowCommonClass.getCanonicalName not implemented");
public ShadowClass getSuperclass () {
return __superClass;
}
......@@ -187,24 +146,7 @@ final class ObjectShadowClass extends ShadowClass {
return __classNode.interfaces.toArray (new String [0]);
}
@Override
public String getPackage () {
final int i = __name.lastIndexOf ('.');
if (i != -1) {
return __name.substring (0, i);
} else {
return null;
}
}
@Override
public ShadowClass getSuperclass () {
return __superClass;
}
//
@Override
public FieldInfo [] getFields () {
......@@ -249,7 +191,7 @@ final class ObjectShadowClass extends ShadowClass {
}
throw new NoSuchMethodException (
__name + "." + methodName + argumentNamesToString (argumentNames)
__name + "." + methodName + _descriptorsToString (argumentNames)
);
}
......@@ -279,13 +221,6 @@ final class ObjectShadowClass extends ShadowClass {
return methods.toArray (new MethodInfo [methods.size ()]);
}
@Override
public String [] getDeclaredClasses () {
return innerclasses.toArray (new String [innerclasses.size ()]);
}
@Override
public MethodInfo getDeclaredMethod (
final String methodName, final String [] argumentNames
......@@ -299,8 +234,15 @@ final class ObjectShadowClass extends ShadowClass {
}
throw new NoSuchMethodException (
__name + "." + methodName + argumentNamesToString (argumentNames)
__name + "." + methodName + _descriptorsToString (argumentNames)
);
}
//
@Override
public String [] getDeclaredClasses () {
return innerclasses.toArray (new String [innerclasses.size ()]);
}
}
package ch.usi.dag.dislreserver.shadow;
import java.lang.reflect.Modifier;
import org.objectweb.asm.Type;
final class PrimitiveShadowClass extends ShadowClass {
private final Type __type;
//
PrimitiveShadowClass (
final long netReference, final Type type,
final ShadowObject classLoader
) {
super (netReference, classLoader);
__type = type;
super (netReference, type, classLoader);
}
//
@Override
public boolean isArray () {
return false;
}
@Override
public ShadowClass getComponentType () {
return null;
}
@Override
public boolean isInstance (final ShadowObject obj) {
return false;
}
@Override
public boolean isAssignableFrom (final ShadowClass klass) {
return equals (klass);
public int getModifiers () {
// Primitive type classes are ABSTRACT, FINAL, and PUBLIC.
return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC;
}
//
/**
* @see Class#isInstance(Object)
*/
@Override
public boolean isInterface () {
return false;
}
@Override
public boolean isPrimitive () {
return true;
}
@Override
public boolean isAnnotation () {
return false;
}
@Override
public boolean isSynthetic () {
public boolean isInstance (final ShadowObject object) {
return false;
}
/**
* @see Class#isAssignableFrom(Class)
*/
@Override
public boolean isEnum () {
return false;
public boolean isAssignableFrom (final ShadowClass other) {
return this.equals (other);
}
//
/**
* @see Class#getName()
*/
@Override
public String getName () {
return __type.getClassName ();
// Avoid Type.getInternalName() -- returns null for primitive types.
return getCanonicalName ();
}
//
/**
* @see Class#getSuperclass()
*/
@Override
public String getCanonicalName () {
return getName ();
public ShadowClass getSuperclass () {
return null;
}
......@@ -90,30 +68,33 @@ final class PrimitiveShadowClass extends ShadowClass {
return new String [0];
}
//
@Override
public String getPackage () {
return null;
public FieldInfo getField (final String fieldName) throws NoSuchFieldException {
throw new NoSuchFieldException (getCanonicalName () + "." + fieldName);
}
@Override
public ShadowClass getSuperclass () {
return null;
public FieldInfo [] getFields () {
return new FieldInfo [0];
}
//
@Override
public FieldInfo [] getFields () {
return new FieldInfo [0];
public FieldInfo getDeclaredField (final String fieldName) throws NoSuchFieldException {
throw new NoSuchFieldException (getCanonicalName () + "." + fieldName);
}
@Override
public FieldInfo getField (final String fieldName) throws NoSuchFieldException {
throw new NoSuchFieldException (__type.getClassName () + "." + fieldName);
public FieldInfo [] getDeclaredFields () {
return new FieldInfo [0];
}
//
@Override
public MethodInfo [] getMethods () {
......@@ -126,28 +107,11 @@ final class PrimitiveShadowClass extends ShadowClass {
final String methodName, final String [] argumentNames
) throws NoSuchMethodException {
throw new NoSuchMethodException (
__type.getClassName () + "." + methodName + argumentNamesToString (argumentNames)
getCanonicalName () + "." + methodName + _descriptorsToString (argumentNames)
);
}
@Override
public String [] getDeclaredClasses () {
return new String [0];
}
@Override
public FieldInfo [] getDeclaredFields () {
return new FieldInfo [0];
}
@Override
public FieldInfo getDeclaredField (final String fieldName) throws NoSuchFieldException {
throw new NoSuchFieldException (__type.getClassName () + "." + fieldName);
}
//
@Override
public MethodInfo [] getDeclaredMethods () {
......@@ -160,8 +124,15 @@ final class PrimitiveShadowClass extends ShadowClass {
final String methodName, final String [] argumentNames
) throws NoSuchMethodException {
throw new NoSuchMethodException (
__type.getClassName () + "." + methodName + argumentNamesToString (argumentNames)
getCanonicalName () + "." + methodName + _descriptorsToString (argumentNames)
);
}
//
@Override
public String [] getDeclaredClasses () {
return new String [0];
}
}
package ch.usi.dag.dislreserver.shadow;
import java.util.Arrays;
import java.util.Formatter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
public abstract class ShadowClass extends ShadowObject {
/**
* The type (class) represented by this shadow class.
*/
private final Type __type;
private final ShadowObject __classLoader;
//
protected ShadowClass (
final long netReference, final ShadowObject classLoader
final long netReference, final Type type,
final ShadowObject classLoader
) {
super (netReference, null);
super (netReference, null /* indicates Class instance */);
__type = type;
__classLoader = classLoader;
}
//
// No need to expose the interface to user
// getId() should be sufficient
protected final int getClassId () {
// No need to expose the interface to user. getId() should be sufficient
protected final int _classId () {
return NetReferenceHelper.getClassId (getNetRef ());
}
public final ShadowObject getShadowClassLoader () {
return __classLoader;
protected final Type _type () {
return __type;
}
//
public abstract boolean isArray ();
@Override
public boolean equals (final Object object) {
//
// Two shadow classes are considered equal if they represent the
// same class and have been loaded by the same class loader.
//
if (object instanceof ShadowClass) {
final ShadowClass that = (ShadowClass) object;
if (this.getName ().equals (that.getName ())) {
return this.getShadowClassLoader ().equals (
that.getShadowClassLoader ()
);
}
}
return false;
}
public abstract ShadowClass getComponentType ();