diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index 5115a29b..0d467b77 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -30,6 +30,7 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.result.GenericInsertPair; +import de.dhbwstuttgart.typeinference.result.ResolvedType; import de.dhbwstuttgart.typeinference.result.ResultPair; import de.dhbwstuttgart.typeinference.result.ResultSet; @@ -54,8 +55,8 @@ public class BytecodeGen implements ASTVisitor { // stores generics and their bounds of method HashMap genericsAndBoundsMethod = new HashMap<>(); + private final TPHExtractor tphExtractor = new TPHExtractor(); private final ArrayList commonPairs = new ArrayList<>(); - private ArrayList ListOfMethodsAndTph = new ArrayList<>(); HashMap methodParamsAndTypes = new HashMap<>(); byte[] bytecode; @@ -115,11 +116,10 @@ public class BytecodeGen implements ASTVisitor { resultSet = rs; // Nur einmal ausführen!! if(!isVisited) { - TPHExtractor tphExtractor = new TPHExtractor(); classOrInterface.accept(tphExtractor); getCommonTPHS(tphExtractor); - ListOfMethodsAndTph = tphExtractor.ListOfMethodsAndTph; + String sig = null; /* if class has generics then creates signature * Signature looks like: @@ -164,26 +164,6 @@ public class BytecodeGen implements ASTVisitor { if(!tphExtractor.allTPHS.get(tph)) cTPHs.add(tph); } - - ArrayList 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 @@ -268,14 +248,10 @@ public class BytecodeGen implements ASTVisitor { /* if method has generics or return type is TPH, create signature */ // zwite operand muss weggelassen werden if(hasGen||method.getReturnType().acceptTV(new TypeToString()).equals("TPH")) { - ArrayList pairs = new ArrayList<>(); - for(MethodAndTPH m : ListOfMethodsAndTph) { - if(m.getName().equals(method.name)) { - pairs = m.getPairs(); - break; - } - } + ArrayList 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); sig = signature.toString(); } @@ -294,6 +270,70 @@ public class BytecodeGen implements ASTVisitor { mv.visitEnd(); } + private ArrayList simplifyPairs(String methodName, ArrayList allPairs) { + ArrayList simplifiedPairs = new ArrayList<>(); + + MethodAndTPH method; + ArrayList methodTphs = new ArrayList<>(); + ArrayList methodPairs = new ArrayList<>(); + for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) { + if(m.getName().equals(methodName)) { + methodTphs = m.getTphs(); + methodPairs = m.getPairs(); + break; + } + } + + HashMap 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 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 public void visit(ParameterList formalParameters) { paramsAndLocals = new HashMap<>(); @@ -553,6 +593,7 @@ public class BytecodeGen implements ASTVisitor { methodAndTph.getTphs().add(resolvedTPH); allTPHS.put(resolvedTPH,inMethod); + ResolvedType rst = resultSet.resolveType(tph); resultSet.resolveType(tph).additionalGenerics.forEach(ag ->{ if(ag.contains(resolvedTPH)&&ag.TA1.equals(resolvedTPH)&&!contains(allPairs,ag)) { if(inMethod) diff --git a/src/de/dhbwstuttgart/bytecode/signature/Signature.java b/src/de/dhbwstuttgart/bytecode/signature/Signature.java index 51329a55..2860cc83 100644 --- a/src/de/dhbwstuttgart/bytecode/signature/Signature.java +++ b/src/de/dhbwstuttgart/bytecode/signature/Signature.java @@ -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