|
|
|
@ -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<E>(Vector<E> 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<parameterTypes.length; i++) |
|
|
|
|