TPH X < TPH Y <...< TPH Z vereinfacht => TPH X < TPH Z und Signature-Erzeugung wird angepasst

This commit is contained in:
Fayez Abu Alia 2018-06-19 13:31:39 +02:00
parent 2db5ecc260
commit 6d70464a1c
2 changed files with 71 additions and 40 deletions

View File

@ -30,6 +30,7 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType; import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
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.ResultPair; import de.dhbwstuttgart.typeinference.result.ResultPair;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
@ -54,8 +55,8 @@ public class BytecodeGen implements ASTVisitor {
// stores generics and their bounds of method // stores generics and their bounds of method
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>(); HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
private final TPHExtractor tphExtractor = new TPHExtractor();
private final ArrayList<GenericInsertPair> commonPairs = new ArrayList<>(); private final ArrayList<GenericInsertPair> commonPairs = new ArrayList<>();
private ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes = new HashMap<>(); HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes = new HashMap<>();
byte[] bytecode; byte[] bytecode;
@ -115,11 +116,10 @@ public class BytecodeGen implements ASTVisitor {
resultSet = rs; resultSet = rs;
// Nur einmal ausführen!! // Nur einmal ausführen!!
if(!isVisited) { if(!isVisited) {
TPHExtractor tphExtractor = new TPHExtractor();
classOrInterface.accept(tphExtractor); classOrInterface.accept(tphExtractor);
getCommonTPHS(tphExtractor); getCommonTPHS(tphExtractor);
ListOfMethodsAndTph = tphExtractor.ListOfMethodsAndTph;
String sig = null; String sig = null;
/* if class has generics then creates signature /* if class has generics then creates signature
* Signature looks like: * Signature looks like:
@ -164,26 +164,6 @@ public class BytecodeGen implements ASTVisitor {
if(!tphExtractor.allTPHS.get(tph)) if(!tphExtractor.allTPHS.get(tph))
cTPHs.add(tph); cTPHs.add(tph);
} }
ArrayList<MethodAndTPH> tphsMethod = tphExtractor.ListOfMethodsAndTph;
// Für jede Methode speichere die gemeinsame TPHs:
// -> Für jedes Pair prüfe ob, auf der rechten Seite ein TPH steht, der
// in der Liste der TPHs der Methode enthalten ist.
// Wenn ja -> gemeinsamer TPH
for(MethodAndTPH m:tphsMethod){
for(GenericInsertPair p : m.getPairs()){
if(!m.getTphs().contains(p.TA2))
cTPHs.add(p.TA2);
}
}
for(TypePlaceholder tph : cTPHs) {
for(GenericInsertPair p : tphExtractor.allPairs) {
if(p.contains(tph))
commonPairs.add(p);
}
}
} }
@Override @Override
@ -268,14 +248,10 @@ public class BytecodeGen implements ASTVisitor {
/* if method has generics or return type is TPH, create signature */ /* if method has generics or return type is TPH, create signature */
// zwite operand muss weggelassen werden // zwite operand muss weggelassen werden
if(hasGen||method.getReturnType().acceptTV(new TypeToString()).equals("TPH")) { if(hasGen||method.getReturnType().acceptTV(new TypeToString()).equals("TPH")) {
ArrayList<GenericInsertPair> pairs = new ArrayList<>();
for(MethodAndTPH m : ListOfMethodsAndTph) {
if(m.getName().equals(method.name)) {
pairs = m.getPairs();
break;
}
}
ArrayList<GenericInsertPair> pairs = simplifyPairs(method.name,tphExtractor.allPairs);
System.out.println(method.name + " => Simplified Pairs: ");
pairs.forEach(p->System.out.println(p.TA1.getName() + " -> "+p.TA2.getName()));
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet, pairs); Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet, pairs);
sig = signature.toString(); sig = signature.toString();
} }
@ -294,6 +270,70 @@ public class BytecodeGen implements ASTVisitor {
mv.visitEnd(); mv.visitEnd();
} }
private ArrayList<GenericInsertPair> simplifyPairs(String methodName, ArrayList<GenericInsertPair> allPairs) {
ArrayList<GenericInsertPair> simplifiedPairs = new ArrayList<>();
MethodAndTPH method;
ArrayList<TypePlaceholder> methodTphs = new ArrayList<>();
ArrayList<GenericInsertPair> methodPairs = new ArrayList<>();
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
if(m.getName().equals(methodName)) {
methodTphs = m.getTphs();
methodPairs = m.getPairs();
break;
}
}
HashMap<TypePlaceholder, TypePlaceholder> subAndSuperTph = new HashMap<>();
for(GenericInsertPair p : allPairs) {
subAndSuperTph.put(p.TA1, p.TA2);
}
int numOfVisitedPairs = 0;
for(TypePlaceholder subTph: subAndSuperTph.keySet()) {
if(numOfVisitedPairs>=subAndSuperTph.size())
break;
if(!methodTphs.contains(subTph))
continue;
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++;
}
// 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
TypePlaceholder subTphRes = tphsInRel.get(0);
// Die größte Supertype
TypePlaceholder superTphRes = tphsInRel.get(tphsInRel.size()-1);
int i = 2;
while(!methodTphs.contains(superTphRes) && (tphsInRel.size()-i) >0) {
superTphRes = tphsInRel.get(tphsInRel.size()-i);
i++;
}
GenericInsertPair sPair = new GenericInsertPair(subTphRes, superTphRes);
simplifiedPairs.add(sPair);
}
return simplifiedPairs;
}
@Override @Override
public void visit(ParameterList formalParameters) { public void visit(ParameterList formalParameters) {
paramsAndLocals = new HashMap<>(); paramsAndLocals = new HashMap<>();
@ -553,6 +593,7 @@ 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)

View File

@ -147,16 +147,6 @@ public class Signature {
} }
} }
// methodPairs.forEach(p->{
// String name = p.TA2.getName() + "$";
// if(!genericsAndBoundsMethod.containsKey(name)) {
// sw.visitFormalTypeParameter(name);
// String bound = Type.getInternalName(Object.class);
// sw.visitClassBound().visitClassType(bound);
// sw.visitClassBound().visitEnd();
// genericsAndBoundsMethod.put(name, bound);
// }
// });
} }
// visit each method-parameter to create the signature // visit each method-parameter to create the signature