Enable methods to declare generics

git-svn-id: https://svn.code.sf.net/p/jode/code/branches/generics@1409 379699f6-c40d-0410-875b-85095c16579e
generics
hoenicke 16 years ago
parent ec94bc4489
commit c2bcab17c3
  1. 1
      jode/src/net/sf/jode/bytecode/Block.java
  2. 2
      jode/src/net/sf/jode/decompiler/MethodAnalyzer.java
  3. 7
      jode/src/net/sf/jode/expr/InvokeOperator.java
  4. 3
      jode/src/net/sf/jode/type/ClassInfoType.java
  5. 16
      jode/src/net/sf/jode/type/ClassType.java
  6. 5
      jode/src/net/sf/jode/type/GenericDeclarer.java
  7. 42
      jode/src/net/sf/jode/type/MethodType.java
  8. 9
      jode/src/net/sf/jode/type/Type.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]);
}
}

@ -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("<init>") || methodName.equals("<clinit>");

@ -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*/

@ -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);

@ -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);

@ -0,0 +1,5 @@
package net.sf.jode.type;
public interface GenericDeclarer {
public Type getGeneric(String name);
}

@ -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++)

@ -211,7 +211,7 @@ public class Type {
return tType(declarer.getClassPath(), null, signature);
}
public static final ClassInfoType tClassSig(ClassPath cp, ClassType declarer,
public static final ClassInfoType tClassSig(ClassPath cp, GenericDeclarer declarer,
String signature)
{
Type[] generics = null;
@ -266,7 +266,7 @@ public class Type {
* @param type the type signature (or method signature).
* @return a singleton set containing the given type.
*/
public static final Type tType(ClassPath cp, ClassType declarer,
public static final Type tType(ClassPath cp, GenericDeclarer declarer,
String signature) {
if (signature == null || signature.length() == 0)
return tError;
@ -429,8 +429,9 @@ public class Type {
* @param signature the method descriptor.
* @return a method type (a singleton set).
*/
public static MethodType tMethod(ClassPath cp, ClassType declarer, String signature) {
return new MethodType(cp, declarer, signature);
public static MethodType tMethod(ClassPath cp, GenericDeclarer declarer,
String signature, Type[] generics) {
return new MethodType(cp, declarer, signature, generics);
}
/**

Loading…
Cancel
Save