From c2bcab17c3331b77e81408fc98e504ad9cf88c07 Mon Sep 17 00:00:00 2001 From: hoenicke Date: Sat, 26 Jul 2008 19:38:15 +0000 Subject: [PATCH] Enable methods to declare generics git-svn-id: https://svn.code.sf.net/p/jode/code/branches/generics@1409 379699f6-c40d-0410-875b-85095c16579e --- jode/src/net/sf/jode/bytecode/Block.java | 1 + .../sf/jode/decompiler/MethodAnalyzer.java | 2 +- jode/src/net/sf/jode/expr/InvokeOperator.java | 7 +++- jode/src/net/sf/jode/type/ClassInfoType.java | 3 +- jode/src/net/sf/jode/type/ClassType.java | 16 +++---- .../src/net/sf/jode/type/GenericDeclarer.java | 5 +++ jode/src/net/sf/jode/type/MethodType.java | 42 +++++++++++++++---- jode/src/net/sf/jode/type/Type.java | 9 ++-- 8 files changed, 60 insertions(+), 25 deletions(-) create mode 100644 jode/src/net/sf/jode/type/GenericDeclarer.java diff --git a/jode/src/net/sf/jode/bytecode/Block.java b/jode/src/net/sf/jode/bytecode/Block.java index dcf6aeb..bb55482 100644 --- a/jode/src/net/sf/jode/bytecode/Block.java +++ b/jode/src/net/sf/jode/bytecode/Block.java @@ -280,6 +280,7 @@ public final class Block { if (succs[succs.length-1] == null) output.println("\treturn"); else + output.println("\tgoto "+succs[succs.length-1]); } } diff --git a/jode/src/net/sf/jode/decompiler/MethodAnalyzer.java b/jode/src/net/sf/jode/decompiler/MethodAnalyzer.java index b41d72d..28bc22a 100644 --- a/jode/src/net/sf/jode/decompiler/MethodAnalyzer.java +++ b/jode/src/net/sf/jode/decompiler/MethodAnalyzer.java @@ -247,7 +247,7 @@ public class MethodAnalyzer implements Scope, ClassDeclarer { } } - this.methodType = Type.tMethod(cla.getClassPath(), cla.getType(), signature); + this.methodType = Type.tMethod(cla.getClassPath(), cla.getType(), signature, genericTypes); this.isConstructor = methodName.equals("") || methodName.equals(""); diff --git a/jode/src/net/sf/jode/expr/InvokeOperator.java b/jode/src/net/sf/jode/expr/InvokeOperator.java index 44b181e..e9429bd 100644 --- a/jode/src/net/sf/jode/expr/InvokeOperator.java +++ b/jode/src/net/sf/jode/expr/InvokeOperator.java @@ -155,8 +155,9 @@ public final class InvokeOperator extends Operator super(Type.tUnknown, 0); this.classPath = methodAnalyzer.getClassAnalyzer().getClassPath(); this.ref = reference; + //TODO: generics this.methodType = Type.tMethod(methodAnalyzer.getClassPath(), - null, reference.getType()); + null, reference.getType(), null); this.methodName = reference.getName(); this.classType = (ClassType) Type.tType(methodAnalyzer.getClassPath(), null, reference.getClazz()); @@ -774,8 +775,10 @@ public final class InvokeOperator extends Operator /* method name doesn't match*/ continue next_method; + // TODO Generics Type[] otherParamTypes - = Type.tMethod(methodAnalyzer.getClassPath(), null, methods[i].getSignature()) + = Type.tMethod(methodAnalyzer.getClassPath(), null, + methods[i].getSignature(), null) .getParameterTypes(); if (otherParamTypes.length != myParamTypes.length) { /* parameter count doesn't match*/ diff --git a/jode/src/net/sf/jode/type/ClassInfoType.java b/jode/src/net/sf/jode/type/ClassInfoType.java index 710018b..41cdb48 100644 --- a/jode/src/net/sf/jode/type/ClassInfoType.java +++ b/jode/src/net/sf/jode/type/ClassInfoType.java @@ -44,7 +44,7 @@ public class ClassInfoType extends ClassType { } public ClassInfoType(ClassInfo clazz, Type[] generics, - ClassType outerClass) { + GenericDeclarer outerClass) { super(TC_CLASS, clazz.getName(), outerClass); this.clazz = clazz; @@ -68,7 +68,6 @@ public class ClassInfoType extends ClassType { } genericInstances = generics; - Map genericMap = new SimpleMap(); if (generics != null) { /* parse generic names */ genericNames = TypeSignature.getGenericNames(signature); diff --git a/jode/src/net/sf/jode/type/ClassType.java b/jode/src/net/sf/jode/type/ClassType.java index d6f0c52..f2dae83 100644 --- a/jode/src/net/sf/jode/type/ClassType.java +++ b/jode/src/net/sf/jode/type/ClassType.java @@ -26,14 +26,14 @@ import java.util.Stack; * * @author Jochen Hoenicke */ -public abstract class ClassType extends ReferenceType { +public abstract class ClassType extends ReferenceType implements GenericDeclarer { /** * The full qualified class name in java syntax. */ protected String className; protected String[] genericNames; protected Type[] genericInstances; - protected ClassType outerClass; + protected GenericDeclarer outerClass; /* * @invariant (genericNames == null) == (genericInstances == null) @@ -41,6 +41,12 @@ public abstract class ClassType extends ReferenceType { * (genericNames.length == genericInstances.length) */ + public ClassType(int typecode, String clazzName, GenericDeclarer outerClass) { + super(typecode); + className = clazzName; + this.outerClass = outerClass; + } + public String getClassName() { return className; } @@ -56,12 +62,6 @@ public abstract class ClassType extends ReferenceType { return null; } - public ClassType(int typecode, String clazzName, ClassType outerClass) { - super(typecode); - className = clazzName; - this.outerClass = outerClass; - } - public ClassType(int typecode, String clazzName, String[] genNames, Type[] genTypes) { super(typecode); diff --git a/jode/src/net/sf/jode/type/GenericDeclarer.java b/jode/src/net/sf/jode/type/GenericDeclarer.java new file mode 100644 index 0000000..1819e87 --- /dev/null +++ b/jode/src/net/sf/jode/type/GenericDeclarer.java @@ -0,0 +1,5 @@ +package net.sf.jode.type; + +public interface GenericDeclarer { + public Type getGeneric(String name); +} diff --git a/jode/src/net/sf/jode/type/MethodType.java b/jode/src/net/sf/jode/type/MethodType.java index 9e6e7af..709f5ce 100644 --- a/jode/src/net/sf/jode/type/MethodType.java +++ b/jode/src/net/sf/jode/type/MethodType.java @@ -18,26 +18,32 @@ */ package net.sf.jode.type; +import java.util.Map; + import net.sf.jode.bytecode.ClassPath; import net.sf.jode.bytecode.TypeSignature; import net.sf.jode.decompiler.ClassDeclarer; +import net.sf.jode.util.SimpleMap; /** * This type represents an method type. * * @author Jochen Hoenicke */ -public class MethodType extends Type { +public class MethodType extends Type implements GenericDeclarer { final String signature; final Type[] parameterTypes; final Type returnType; + final String[] genericNames; + final Type[] genericInstances; + final GenericDeclarer declarer; final ClassPath cp; - public MethodType(ClassPath cp, ClassType declarer, String signature) { + public MethodType(ClassPath cp, GenericDeclarer declarer, String signature, Type[] generics) { /* TODO: * We need TypeVariable: e.g. iff we have * E getElm(Vector v); - * then E is a TypeVariable and if we now, that input type is a + * then E is a TypeVariable and if we know, that input type is a * vector of Integer, then return value is Integer... * * A problem is that casts of v omit the value for E. @@ -45,19 +51,39 @@ public class MethodType extends Type { super(TC_METHOD); this.cp = cp; this.signature = signature; - if (signature.charAt(0) == '<') { - /* handled by MethodAnalyzer */ - signature = signature.substring(signature.indexOf('(')); + this.declarer = declarer; + genericInstances = generics; + genericNames = TypeSignature.getGenericNames(signature); + if (generics != null) { + /* parse generic names */ + if (generics.length != genericNames.length) + throw new IllegalArgumentException + ("Wrong number of generic parameters"); } + if (signature.charAt(0) == '<') + signature = signature.substring(signature.indexOf('(')); + String[] params = TypeSignature.getParameterTypes(signature); parameterTypes = new Type[params.length]; for (int i = 0; i < params.length; i++) { - parameterTypes[i] = Type.tType(cp, declarer, params[i]); + parameterTypes[i] = Type.tType(cp, this, params[i]); } - returnType = Type.tType(cp, declarer, + returnType = Type.tType(cp, this, TypeSignature.getReturnType(signature)); } + + public Type getGeneric(String name) { + if (genericInstances != null && /*TODO */ genericNames != null) { + for (int i = 0; i < genericNames.length; i++) + if (genericNames[i].equals(name)) + return genericInstances[i]; + } + if (declarer != null) + return declarer.getGeneric(name); + return null; + } + public final int stackSize() { int size = returnType.stackSize(); for (int i=0; i