Commit 520a4395 authored by Yudi Zheng's avatar Yudi Zheng

Restore FieldInfo and MethodInfo as well as the corresponding reflection API.

parent 03b93dad
package ch.usi.dag.dislreserver.shadow;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.FieldNode;
public class FieldInfo {
// TODO ! is this implementation of methods really working ??
private FieldNode fieldNode;
private int modifiers;
private String name;
private String type;
public FieldInfo(FieldNode fieldNode) {
this.fieldNode = fieldNode;
name = fieldNode.name;
type = fieldNode.desc;
modifiers = fieldNode.access;
}
public FieldNode getFieldNode() {
return fieldNode;
}
public String getName() {
return name;
}
public int getModifiers() {
return modifiers;
}
public String getType() {
return type;
}
public boolean isPublic() {
return (modifiers & Opcodes.ACC_PUBLIC) != 0;
}
}
package ch.usi.dag.dislreserver.shadow;
import java.util.Arrays;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.MethodNode;
public class MethodInfo {
// TODO ! is this implementation of methods really working ??
private MethodNode methodNode;
private int modifiers;
private String name;
private String returnType;
private String[] parameterTypes;
private String[] exceptionTypes;
public MethodInfo(MethodNode methodNode) {
this.methodNode = methodNode;
name = methodNode.name;
modifiers = methodNode.access;
returnType = methodNode.desc
.substring(methodNode.desc.indexOf(')') + 1);
Type[] parameters = Type.getArgumentTypes(methodNode.desc);
int size = parameters.length;
parameterTypes = new String[size];
for (int i = 0; i < size; i++) {
parameterTypes[i] = parameters[i].getDescriptor();
}
// to have "checked" array :(
exceptionTypes = methodNode.exceptions.toArray(new String[0]);
}
public MethodNode getMethodNode() {
return methodNode;
}
public String getName() {
return name;
}
public int getModifiers() {
return modifiers;
}
public String getReturnType() {
return returnType;
}
public String[] getParameterTypes() {
return Arrays.copyOf(parameterTypes, parameterTypes.length);
}
public String[] getExceptionTypes() {
return Arrays.copyOf(exceptionTypes, exceptionTypes.length);
}
public boolean isPublic() {
return (modifiers & Opcodes.ACC_PUBLIC) != 0;
}
}
package ch.usi.dag.dislreserver.shadow;
import java.util.Arrays;
import org.objectweb.asm.Type;
import ch.usi.dag.dislreserver.exception.DiSLREServerFatalException;
......@@ -98,4 +100,63 @@ public class ShadowArrayClass extends ShadowClass {
return superClass;
}
@Override
public FieldInfo[] getFields() {
return new FieldInfo[0];
}
@Override
public FieldInfo getField(String fieldName) throws NoSuchFieldException {
throw new NoSuchFieldException(t.getClassName() + "." + fieldName);
}
@Override
public MethodInfo[] getMethods() {
return getSuperclass().getMethods();
}
@Override
public MethodInfo getMethod(String methodName, String[] argumentNames)
throws NoSuchMethodException {
for (MethodInfo methodInfo : superClass.getMethods()) {
if (methodName.equals(methodInfo.getName())
&& Arrays.equals(argumentNames,
methodInfo.getParameterTypes())) {
return methodInfo;
}
}
throw new NoSuchMethodException(t.getClassName() + "." + methodName
+ argumentNamesToString(argumentNames));
}
@Override
public String[] getDeclaredClasses() {
return new String[0];
}
@Override
public FieldInfo[] getDeclaredFields() {
return new FieldInfo[0];
}
@Override
public FieldInfo getDeclaredField(String fieldName)
throws NoSuchFieldException {
throw new NoSuchFieldException(t.getClassName() + "." + fieldName);
}
@Override
public MethodInfo[] getDeclaredMethods() {
return new MethodInfo[0];
}
@Override
public MethodInfo getDeclaredMethod(String methodName,
String[] argumentNames) throws NoSuchMethodException {
throw new NoSuchMethodException(t.getClassName() + "." + methodName
+ argumentNamesToString(argumentNames));
}
}
......@@ -64,4 +64,73 @@ public abstract class ShadowClass extends ShadowObject {
return false;
}
public abstract FieldInfo[] getFields();
public abstract FieldInfo getField(String fieldName)
throws NoSuchFieldException;
public abstract MethodInfo[] getMethods();
public abstract MethodInfo getMethod(String methodName,
String[] argumentNames) throws NoSuchMethodException;
public abstract String[] getDeclaredClasses();
public abstract FieldInfo[] getDeclaredFields();
public abstract FieldInfo getDeclaredField(String fieldName)
throws NoSuchFieldException;
public abstract MethodInfo[] getDeclaredMethods();
public abstract MethodInfo getDeclaredMethod(String methodName,
String[] argumentNames) throws NoSuchMethodException;
public MethodInfo getMethod(String methodName, ShadowClass[] arguments)
throws NoSuchMethodException {
return getMethod(methodName, classesToStrings(arguments));
}
public MethodInfo getDeclaredMethod(String methodName,
ShadowClass[] arguments) throws NoSuchMethodException {
return getDeclaredMethod(methodName, classesToStrings(arguments));
}
protected static String[] classesToStrings(ShadowClass[] arguments) {
if (arguments == null) {
return new String[0];
}
int size = arguments.length;
String[] argumentNames = new String[size];
for (int i = 0; i < size; i++) {
argumentNames[i] = arguments[i].getName();
}
return argumentNames;
}
protected static String argumentNamesToString(String[] argumentNames) {
StringBuilder buf = new StringBuilder();
buf.append("(");
if (argumentNames != null) {
for (int i = 0; i < argumentNames.length; i++) {
if (i > 0) {
buf.append(", ");
}
buf.append(argumentNames[i]);
}
}
buf.append(")");
return buf.toString();
}
}
\ No newline at end of file
package ch.usi.dag.dislreserver.shadow;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InnerClassNode;
import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.dislreserver.exception.DiSLREServerFatalException;
class ShadowCommonClass extends ShadowClass {
// TODO ! is this implementation of methods really working ??
private ShadowClass superClass;
private ClassNode classNode;
......@@ -21,6 +33,22 @@ class ShadowCommonClass extends ShadowClass {
this.classGenericStr = classGenericStr;
this.superClass = superClass;
if (classCode == null || classCode.length == 0) {
throw new DiSLREServerFatalException("Creating class info for "
+ classSignature + " with no code provided");
}
initializeClassInfo(classCode);
}
private List<MethodInfo> methods;
private List<MethodInfo> public_methods;
private List<FieldInfo> fields;
private List<FieldInfo> public_fields;
private List<String> innerclasses;
private void initializeClassInfo(byte[] classCode) {
ClassReader classReader = new ClassReader(classCode);
classNode = new ClassNode(Opcodes.ASM4);
......@@ -29,6 +57,49 @@ class ShadowCommonClass extends ShadowClass {
access = classNode.access;
name = classNode.name.replace('/', '.');
methods = new ArrayList<MethodInfo>(classNode.methods.size());
public_methods = new LinkedList<MethodInfo>();
for (MethodNode methodNode : classNode.methods) {
MethodInfo methodInfo = new MethodInfo(methodNode);
methods.add(methodInfo);
if (methodInfo.isPublic()) {
public_methods.add(methodInfo);
}
}
fields = new ArrayList<FieldInfo>(classNode.fields.size());
public_fields = new LinkedList<FieldInfo>();
for (FieldNode fieldNode : classNode.fields) {
FieldInfo fieldInfo = new FieldInfo(fieldNode);
fields.add(fieldInfo);
if (fieldInfo.isPublic()) {
public_fields.add(fieldInfo);
}
}
if (getSuperclass() != null) {
for (MethodInfo methodInfo : getSuperclass().getMethods()) {
public_methods.add(methodInfo);
}
for (FieldInfo fieldInfo : getSuperclass().getFields()) {
public_fields.add(fieldInfo);
}
}
innerclasses = new ArrayList<String>(classNode.innerClasses.size());
for (InnerClassNode innerClassNode : classNode.innerClasses) {
innerclasses.add(innerClassNode.name);
}
}
@Override
......@@ -43,24 +114,25 @@ class ShadowCommonClass extends ShadowClass {
@Override
public boolean isInstance(ShadowObject obj) {
// TODO consider interfaces
return equals(obj.getSClass());
// return equals(obj.getSClass());
throw new DiSLREServerFatalException(
"ShadowCommonClass.isInstance not implemented");
}
@Override
public boolean isAssignableFrom(ShadowClass klass) {
// TODO consider interfaces
while (klass != null) {
if (klass.equals(this)) {
return true;
}
klass = klass.getSuperclass();
}
return false;
// while (klass != null) {
//
// if (klass.equals(this)) {
// return true;
// }
//
// klass = klass.getSuperclass();
// }
//
// return false;
throw new DiSLREServerFatalException(
"ShadowCommonClass.isAssignableFrom not implemented");
}
@Override
......@@ -95,7 +167,8 @@ class ShadowCommonClass extends ShadowClass {
@Override
public String getCanonicalName() {
return name;
throw new DiSLREServerFatalException(
"ShadowCommonClass.getCanonicalName not implemented");
}
@Override
......@@ -132,4 +205,85 @@ class ShadowCommonClass extends ShadowClass {
return superClass;
}
public FieldInfo[] getFields() {
// to have "checked" array :(
return public_fields.toArray(new FieldInfo[0]);
}
public FieldInfo getField(String fieldName) throws NoSuchFieldException {
for (FieldInfo fieldInfo : fields) {
if (fieldInfo.isPublic() && fieldInfo.getName().equals(fieldName)) {
return fieldInfo;
}
}
if (getSuperclass() == null) {
throw new NoSuchFieldException(name + "." + fieldName);
}
return getSuperclass().getField(fieldName);
}
public MethodInfo[] getMethods() {
// to have "checked" array :(
return public_methods.toArray(new MethodInfo[0]);
}
public MethodInfo getMethod(String methodName, String[] argumentNames)
throws NoSuchMethodException {
for (MethodInfo methodInfo : public_methods) {
if (methodName.equals(methodInfo.getName())
&& Arrays.equals(argumentNames,
methodInfo.getParameterTypes())) {
return methodInfo;
}
}
throw new NoSuchMethodException(name + "." + methodName
+ argumentNamesToString(argumentNames));
}
public FieldInfo[] getDeclaredFields() {
return (FieldInfo[]) fields.toArray();
}
public FieldInfo getDeclaredField(String fieldName)
throws NoSuchFieldException {
for (FieldInfo fieldInfo : fields) {
if (fieldInfo.getName().equals(fieldName)) {
return fieldInfo;
}
}
throw new NoSuchFieldException(name + "." + fieldName);
}
public MethodInfo[] getDeclaredMethods() {
return (MethodInfo[]) methods.toArray();
}
public String[] getDeclaredClasses() {
return (String[]) innerclasses.toArray();
}
public MethodInfo getDeclaredMethod(String methodName,
String[] argumentNames) throws NoSuchMethodException {
for (MethodInfo methodInfo : methods) {
if (methodName.equals(methodInfo.getName())
&& Arrays.equals(argumentNames,
methodInfo.getParameterTypes())) {
return methodInfo;
}
}
throw new NoSuchMethodException(name + "." + methodName
+ argumentNamesToString(argumentNames));
}
}
......@@ -2,8 +2,6 @@ package ch.usi.dag.dislreserver.shadow;
import org.objectweb.asm.Type;
import ch.usi.dag.dislreserver.exception.DiSLREServerFatalException;
public class ShadowPrimitiveClass extends ShadowClass {
private Type t;
......@@ -61,27 +59,7 @@ public class ShadowPrimitiveClass extends ShadowClass {
@Override
public String getName() {
switch (t.getSort()) {
case Type.BOOLEAN:
return "boolean";
case Type.BYTE:
return "byte";
case Type.CHAR:
return "char";
case Type.DOUBLE:
return "double";
case Type.FLOAT:
return "float";
case Type.INT:
return "int";
case Type.LONG:
return "long";
case Type.SHORT:
return "short";
default:
throw new DiSLREServerFatalException("Unknown primitive type");
}
return t.getClassName();
}
@Override
......@@ -104,4 +82,54 @@ public class ShadowPrimitiveClass extends ShadowClass {
return null;
}
@Override
public FieldInfo[] getFields() {
return new FieldInfo[0];
}
@Override
public FieldInfo getField(String fieldName) throws NoSuchFieldException {
throw new NoSuchFieldException(t.getClassName() + "." + fieldName);
}
@Override
public MethodInfo[] getMethods() {
return new MethodInfo[0];
}
@Override
public MethodInfo getMethod(String methodName, String[] argumentNames)
throws NoSuchMethodException {
throw new NoSuchMethodException(t.getClassName() + "." + methodName
+ argumentNamesToString(argumentNames));
}
@Override
public String[] getDeclaredClasses() {
return new String[0];
}
@Override
public FieldInfo[] getDeclaredFields() {
return new FieldInfo[0];
}
@Override
public FieldInfo getDeclaredField(String fieldName)
throws NoSuchFieldException {
throw new NoSuchFieldException(t.getClassName() + "." + fieldName);
}
@Override
public MethodInfo[] getDeclaredMethods() {
return new MethodInfo[0];
}
@Override
public MethodInfo getDeclaredMethod(String methodName,
String[] argumentNames) throws NoSuchMethodException {
throw new NoSuchMethodException(t.getClassName() + "." + methodName
+ argumentNamesToString(argumentNames));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment