Bug in der Methode simplifyPairs gefixt.

Bug 82 gefixt.
TPHs in paramtrisierten Typen als TypeVariablen in Signature hinzugefügt.
Lambda.jav funktioniert.
This commit is contained in:
Fayez Abu Alia 2018-06-27 14:49:22 +02:00
parent d8bb4d6188
commit b4c604e2b1
8 changed files with 230 additions and 23 deletions

Binary file not shown.

View File

@ -121,7 +121,7 @@ public class BytecodeGen implements ASTVisitor {
// Nur einmal ausführen!! // Nur einmal ausführen!!
if(!isVisited) { if(!isVisited) {
classOrInterface.accept(tphExtractor); classOrInterface.accept(tphExtractor);
getCommonTPHS(tphExtractor); getCommonTPHS(tphExtractor);
String sig = null; String sig = null;
@ -275,6 +275,11 @@ public class BytecodeGen implements ASTVisitor {
} }
private ArrayList<GenericInsertPair> simplifyPairs(String methodName, ArrayList<GenericInsertPair> allPairs) { private ArrayList<GenericInsertPair> simplifyPairs(String methodName, ArrayList<GenericInsertPair> allPairs) {
allPairs.forEach(p->System.out.print(p.TA1 + " < "+ p.TA2+ " ; "));
if(allPairs.size() < 2)
return allPairs;
ArrayList<GenericInsertPair> simplifiedPairs = new ArrayList<>(); ArrayList<GenericInsertPair> simplifiedPairs = new ArrayList<>();
MethodAndTPH method; MethodAndTPH method;
@ -320,22 +325,41 @@ public class BytecodeGen implements ASTVisitor {
numOfVisitedPairs++; numOfVisitedPairs++;
} }
// TODO: teste noch den Fall X < Y und Y nicht in TPHS der Methode
// Dann hat man nach der While-Schleife X < Y
// Y muss durch Object ersetzt.
// Subtype // Subtype
TypePlaceholder subTphRes = tphsInRel.get(0); TypePlaceholder subTphRes = tphsInRel.get(0);
// Die größte Supertype // Die größte Supertype
TypePlaceholder superTphRes = tphsInRel.get(tphsInRel.size()-1); TypePlaceholder superTphRes = tphsInRel.get(tphsInRel.size()-1);
while(subAndSuperTph.containsValue(subTphRes)) {
for(TypePlaceholder tph : subAndSuperTph.keySet()) {
if(methodTphs.contains(tph) && subAndSuperTph.get(tph).equals(subTphRes)) {
subTphRes = tph;
break;
}
}
if(subTphRes.equals(tphsInRel.get(0))) {
break;
}
tphsInRel.put(0, subTphRes);
numOfVisitedPairs++;
}
subTphRes = tphsInRel.get(0);
int i = 2; int i = 2;
while(!methodTphs.contains(superTphRes) && (tphsInRel.size()-i) >0) { while(!methodTphs.contains(superTphRes) && (tphsInRel.size()-i) >0) {
superTphRes = tphsInRel.get(tphsInRel.size()-i); superTphRes = tphsInRel.get(tphsInRel.size()-i);
i++; i++;
} }
// teste noch den Fall X < Y und Y nicht in TPHS der Methode
// Dann hat man nach der While-Schleife X < Y
// Y muss durch Object ersetzt.
GenericInsertPair sPair = new GenericInsertPair(subTphRes, superTphRes); // Zweite Operand für die Fälle wie in Lambda.jav (Paramtrisierte Typen)
simplifiedPairs.add(sPair); if(methodTphs.contains(superTphRes) || !tphExtractor.allTPHS.containsKey(superTphRes)) {
GenericInsertPair sPair = new GenericInsertPair(subTphRes, superTphRes);
simplifiedPairs.add(sPair);
}
} }
return simplifiedPairs; return simplifiedPairs;
} }
@ -599,7 +623,6 @@ public class BytecodeGen implements ASTVisitor {
methodAndTph.getTphs().add(resolvedTPH); methodAndTph.getTphs().add(resolvedTPH);
allTPHS.put(resolvedTPH,inMethod); allTPHS.put(resolvedTPH,inMethod);
ResolvedType rst = resultSet.resolveType(tph);
resultSet.resolveType(tph).additionalGenerics.forEach(ag ->{ resultSet.resolveType(tph).additionalGenerics.forEach(ag ->{
if(ag.contains(resolvedTPH)&&ag.TA1.equals(resolvedTPH)&&!contains(allPairs,ag)) { if(ag.contains(resolvedTPH)&&ag.TA1.equals(resolvedTPH)&&!contains(allPairs,ag)) {
if(inMethod) if(inMethod)
@ -625,6 +648,7 @@ public class BytecodeGen implements ASTVisitor {
inMethod = false; inMethod = false;
ListOfMethodsAndTph.add(methodAndTph); ListOfMethodsAndTph.add(methodAndTph);
} }
} }
} }

View File

@ -639,6 +639,19 @@ public class BytecodeGenMethod implements StatementVisitor {
public void visit(MethodCall methodCall) { public void visit(MethodCall methodCall) {
//ClassLoader.getSystemClassLoader().loadClass(className).getMethod(name, parameterTypes) //ClassLoader.getSystemClassLoader().loadClass(className).getMethod(name, parameterTypes)
String receiverName = getResolvedType(methodCall.receiver.getType());
System.out.println("Methods of " + receiverName + " ");
ClassLoader cl = ClassLoader.getSystemClassLoader();
try {
java.lang.reflect.Method[] methods = cl.loadClass("java.util.Vector").getMethods();
System.out.println("Methods of " + receiverName + " ");
for(java.lang.reflect.Method m : methods) {
System.out.println(m.getName() + " " + m.toGenericString()+ " ==> ");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Methodcall type : " + resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor())); System.out.println("Methodcall type : " + resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor()));
methodCall.receiver.accept(this); methodCall.receiver.accept(this);

View File

@ -123,9 +123,21 @@ public class DescriptorToString implements DescriptorVisitor{
Iterator<FormalParameter> itr = lambdaExpression.getParams().iterator(); Iterator<FormalParameter> itr = lambdaExpression.getParams().iterator();
while(itr.hasNext()) { while(itr.hasNext()) {
FormalParameter fp = itr.next(); FormalParameter fp = itr.next();
desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()) + ";"; String d = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
if(d.substring(0, 4).equals("TPH ") ||d.contains("<")) {
desc += "L"+Type.getInternalName(Object.class)+ ";";
}else {
desc = desc + "L"+ d + ";";
}
}
String retType = resultSet.resolveType(lambdaExpression.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<")){
desc += ")L"+Type.getInternalName(Object.class)+ ";";
}else {
desc = desc + ")"+"L"+retType+";";
} }
desc = addReturnType(desc, lambdaExpression.getReturnType(), resultSet);
return desc; return desc;
} }
@ -135,9 +147,22 @@ public class DescriptorToString implements DescriptorVisitor{
Iterator<RefTypeOrTPHOrWildcardOrGeneric> itr = samMethod.getArgumentList().iterator(); Iterator<RefTypeOrTPHOrWildcardOrGeneric> itr = samMethod.getArgumentList().iterator();
while(itr.hasNext()) { while(itr.hasNext()) {
RefTypeOrTPHOrWildcardOrGeneric rt = itr.next(); RefTypeOrTPHOrWildcardOrGeneric rt = itr.next();
desc = desc + "L"+resultSet.resolveType(rt).resolvedType.acceptTV(new TypeToDescriptor())+";"; String d = resultSet.resolveType(rt).resolvedType.acceptTV(new TypeToDescriptor());
if(d.substring(0, 4).equals("TPH ") ||d.contains("<")) {
desc += "L"+Type.getInternalName(Object.class)+ ";";
}else {
desc += "L"+ d + ";";
}
}
String retType = resultSet.resolveType(samMethod.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<")){
desc += ")L"+Type.getInternalName(Object.class)+ ";";
}else {
desc = desc + ")"+"L"+retType+";";
} }
desc = desc + ")"+"L"+resultSet.resolveType(samMethod.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+";";
return desc; return desc;
} }

View File

@ -9,6 +9,7 @@ import org.objectweb.asm.signature.SignatureVisitor;
import org.objectweb.asm.signature.SignatureWriter; import org.objectweb.asm.signature.SignatureWriter;
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor; import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker; import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Constructor; import de.dhbwstuttgart.syntaxtree.Constructor;
@ -16,9 +17,11 @@ import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.GenericInsertPair; import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
import de.dhbwstuttgart.typeinference.result.ResolvedType;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
public class Signature { public class Signature {
@ -106,7 +109,7 @@ public class Signature {
// z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object // z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object
String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()); String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
if(ret.substring(0,4).equals("TPH ")) { if(ret.substring(0,4).equals("TPH ")) {
String g = ret.substring(4)+"$"; String g = ret.substring(4,ret.length())+"$";
if(genericsAndBounds.containsKey(g)) { if(genericsAndBounds.containsKey(g)) {
genericsAndBoundsMethod.put(g, genericsAndBounds.get(g)); genericsAndBoundsMethod.put(g, genericsAndBounds.get(g));
}else { }else {
@ -117,13 +120,21 @@ public class Signature {
} }
} }
if(ret.contains("<")) {
RefType ref = (RefType) resultSet.resolveType(method.getReturnType()).resolvedType;
if(hasTPHs(ref)) {
createSignatureForParameterizedType(ref);
}
}
// Parameters // Parameters
for(String paramName : methodParamsAndTypes.keySet()) { for(String paramName : methodParamsAndTypes.keySet()) {
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName); RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
String pT = t.acceptTV(new TypeToSignature()); String pT = t.acceptTV(new TypeToSignature());
// S.o // S.o
if(pT.substring(0,4).equals("TPH ")) { if(pT.substring(0,4).equals("TPH ")) {
String gP = pT.substring(4)+"$"; String gP = pT.substring(4,pT.length())+"$";
if(!genericsAndBounds.containsKey(gP) && !genericsAndBoundsMethod.containsKey(gP)) { if(!genericsAndBounds.containsKey(gP) && !genericsAndBoundsMethod.containsKey(gP)) {
sw.visitFormalTypeParameter(gP); sw.visitFormalTypeParameter(gP);
String bound = Type.getInternalName(Object.class); String bound = Type.getInternalName(Object.class);
@ -147,6 +158,12 @@ public class Signature {
} }
} }
if(pT.contains("<")) {
RefType ref = (RefType) methodParamsAndTypes.get(paramName);
if(hasTPHs(ref))
createSignatureForParameterizedType(ref);
}
for(GenericInsertPair p:methodPairs) { for(GenericInsertPair p:methodPairs) {
String name = p.TA1.getName()+"$"; String name = p.TA1.getName()+"$";
if(!genericsAndBoundsMethod.containsKey(name)) { if(!genericsAndBoundsMethod.containsKey(name)) {
@ -191,6 +208,128 @@ public class Signature {
} }
// sw.visitEnd(); // sw.visitEnd();
} }
private void createSignatureForParameterizedType(RefType ref) {
ArrayList<GenericInsertPair> allPairs = getAllPairs(ref);
allPairs.addAll(methodPairs);
ArrayList<GenericInsertPair> simplifiedPairs = simplifyPairs(allPairs);
HashMap<String, String> names = new HashMap<>();
for(GenericInsertPair pair : simplifiedPairs) {
String sub = pair.TA1.getName()+"$";
String superT = pair.TA2.getName()+"$";
names.put(sub, superT);
}
for(String sub : names.keySet()) {
if(!genericsAndBoundsMethod.containsKey(sub) && !genericsAndBounds.containsKey(sub)) {
sw.visitFormalTypeParameter(sub);
String bound = names.get(sub);
sw.visitClassBound().visitTypeVariable(bound);
genericsAndBoundsMethod.put(sub, bound);
}
}
for(String superT : names.values()) {
if(!names.containsKey(superT)) {
if(!genericsAndBoundsMethod.containsKey(superT) && !genericsAndBounds.containsKey(superT)) {
sw.visitFormalTypeParameter(superT);
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
sw.visitClassBound().visitEnd();
genericsAndBoundsMethod.put(superT, Type.getInternalName(Object.class));
}
}
}
}
private ArrayList<GenericInsertPair> getAllPairs(RefType ref) {
final ArrayList<GenericInsertPair> res = new ArrayList<>();
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
RefTypeOrTPHOrWildcardOrGeneric resolved = resultSet.resolveType(p).resolvedType;
if(resolved instanceof TypePlaceholder) {
resultSet.resolveType(p).additionalGenerics.forEach(ag ->{
if(!contains(res,ag)) {
res.add(ag);
}
});
}
}
return res;
}
private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) {
for(int i=0; i<pairs.size();++i) {
GenericInsertPair p = pairs.get(i);
if(p.TA1.equals(genPair.TA1) && p.TA2.equals(genPair.TA2))
return true;
}
return false;
}
private ArrayList<GenericInsertPair> simplifyPairs(ArrayList<GenericInsertPair> allPairs) {
ArrayList<GenericInsertPair> simplifiedPairs = new ArrayList<>();
HashMap<TypePlaceholder, TypePlaceholder> subAndSuperTph = new HashMap<>();
for(GenericInsertPair p : allPairs) {
subAndSuperTph.put(p.TA1, p.TA2);
}
subAndSuperTph.forEach((k,v)->System.out.println(k.getName() + " || " + v.getName()));
int numOfVisitedPairs = 0;
for(TypePlaceholder subTph: subAndSuperTph.keySet()) {
if(numOfVisitedPairs>=subAndSuperTph.size())
break;
HashMap<Integer, TypePlaceholder> tphsInRel= new HashMap<>();
tphsInRel.put(tphsInRel.size(), subTph);
TypePlaceholder superTph = subAndSuperTph.get(subTph);
tphsInRel.put(tphsInRel.size(), superTph);
numOfVisitedPairs++;
while(subAndSuperTph.containsKey(superTph)) {
superTph = subAndSuperTph.get(superTph);
tphsInRel.put(tphsInRel.size(), superTph);
numOfVisitedPairs++;
}
// Subtype
TypePlaceholder subTphRes = tphsInRel.get(0);
// Die größte Supertype
TypePlaceholder superTphRes = tphsInRel.get(tphsInRel.size()-1);
while(subAndSuperTph.containsValue(subTphRes)) {
for(TypePlaceholder tph : subAndSuperTph.keySet()) {
if(subAndSuperTph.get(tph).equals(subTphRes)) {
subTphRes = tph;
break;
}
}
tphsInRel.put(0, subTphRes);
numOfVisitedPairs++;
}
subTphRes = tphsInRel.get(0);
GenericInsertPair sPair = new GenericInsertPair(subTphRes, superTphRes);
simplifiedPairs.add(sPair);
}
return simplifiedPairs;
}
private boolean hasTPHs(RefType ref) {
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
if(resultSet.resolveType(p).resolvedType instanceof TypePlaceholder)
return true;
}
return false;
}
/** /**
* Visits parameter type or return type with {@link SignatureVisitor} to create * Visits parameter type or return type with {@link SignatureVisitor} to create
* the method signature * the method signature

View File

@ -22,7 +22,12 @@ public class TypeToSignature implements TypeVisitor<String> {
Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = refType.getParaList().iterator(); Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = refType.getParaList().iterator();
while(it.hasNext()){ while(it.hasNext()){
RefTypeOrTPHOrWildcardOrGeneric param = it.next(); RefTypeOrTPHOrWildcardOrGeneric param = it.next();
params += "L"+param.toString().replace(".", "/"); if(param instanceof TypePlaceholder) {
params += "T" + ((TypePlaceholder) param).getName() + "$";
} else {
params += "L"+param.toString().replace(".", "/");
}
if(it.hasNext())params += ";"; if(it.hasNext())params += ";";
} }
params += ";>"; params += ";>";

View File

@ -1,4 +1,4 @@
class Apply { } //class Apply { }
public class Lambda { public class Lambda {
@ -6,7 +6,8 @@ public class Lambda {
var lam1 = (x) -> { var lam1 = (x) -> {
return x; return x;
}; };
return lam1.apply(new Apply()); // return lam1.apply(new Apply());
return lam1;
} }
} }

View File

@ -8,9 +8,9 @@ public class Matrix extends Vector<Vector<Integer>> {
var i = 0; var i = 0;
while(i < size()) { while(i < size()) {
var v1 = this.elementAt(i); var v1 = this.elementAt(i);
var v2 = new Vector<Integer>(); // var v2 = new Vector<Integer>();
var j = 0; // var j = 0;
while(j < v1.size()) { // while(j < v1.size()) {
// var erg = 0; // var erg = 0;
// var k = 0; // var k = 0;
// while(k < v1.size()) { // while(k < v1.size()) {
@ -18,9 +18,9 @@ public class Matrix extends Vector<Vector<Integer>> {
// * m.elementAt(k).elementAt(j); // * m.elementAt(k).elementAt(j);
// k++; } // k++; }
// v2.addElement(new Integer(erg)); // v2.addElement(new Integer(erg));
j++; } // j++; }
ret.addElement(v2); // ret.addElement(v2);
i++; // i++;
} }
return ret; return ret;
} }