From 602216d9e2a4a14709813a92242f33aea25e8617 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Thu, 11 Apr 2019 11:26:54 +0200 Subject: [PATCH] Generics beruecksichtigt --- .../dhbwstuttgart/bytecode/BytecodeGen.java | 39 ++++++---- .../dhbwstuttgart/bytecode/TPHExtractor.java | 78 +++++++++++++++++-- .../bytecode/signature/Signature.java | 4 +- .../bytecode/utilities/Simplify.java | 27 +++++-- .../bytecode/utilities/SimplifyResult.java | 6 +- src/test/java/bytecode/ClassGenLamTest.java | 37 +++++++++ .../bytecode/javFiles/ClassGenLam.jav | 8 ++ 7 files changed, 169 insertions(+), 30 deletions(-) create mode 100644 src/test/java/bytecode/ClassGenLamTest.java create mode 100644 src/test/resources/bytecode/javFiles/ClassGenLam.jav diff --git a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java index 8ae7da1e..d5dba757 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -64,7 +64,7 @@ public class BytecodeGen implements ASTVisitor { private String superClass; - private ArrayList tphsClass; + private ArrayList tphsClass; // stores parameter, local vars and the next index on the local variable table, which use for aload_i, astore_i,... HashMap paramsAndLocals = new HashMap<>(); @@ -156,7 +156,7 @@ public class BytecodeGen implements ASTVisitor { getCommonTPHS(tphExtractor); tphsClass = new ArrayList<>(); - for(TypePlaceholder t : tphExtractor.allTPHS.keySet()) { + for(String t : tphExtractor.allTPHS.keySet()) { if(!tphExtractor.allTPHS.get(t)) tphsClass.add(t); } @@ -172,19 +172,32 @@ public class BytecodeGen implements ASTVisitor { HashMap> constraints = Simplify.simplifyConstraintsClass(tphExtractor,tphsClass); ArrayList consClass = new ArrayList<>(); for(TPHConstraint cons : constraints.keySet()) { - TypePlaceholder right = null; - for(TypePlaceholder tph : tphsClass) { - if(cons.getLeft().equals(tph.getName())) { + String right = null; + boolean isToAdd = false; + for(String tph : tphsClass) { + if(cons.getLeft().equals(tph)) { consClass.add(cons); - right = getTPH(cons.getRight()); + try { + right = getTPH(cons.getRight()); + isToAdd = true; + } catch (NoSuchElementException e) { + continue; + } + } } - if(right != null) { + if(isToAdd) { tphsClass.add(right); - removeFromMethod(right.getName()); + removeFromMethod(right); right = null; + isToAdd= false; } +// if(right != null) { +// tphsClass.add(right); +// removeFromMethod(right); +// right = null; +// } } SimplifyResult sRes = new SimplifyResult(consClass, tphsClass, new HashMap<>()); @@ -239,9 +252,9 @@ public class BytecodeGen implements ASTVisitor { } - private TypePlaceholder getTPH(String name) { - for(TypePlaceholder tph: tphExtractor.allTPHS.keySet()) { - if(tph.getName().equals(name)) + private String getTPH(String name) { + for(String tph: tphExtractor.allTPHS.keySet()) { + if(tph.equals(name)) return tph; } throw new NoSuchElementException("TPH "+name +" does not exist"); @@ -249,9 +262,9 @@ public class BytecodeGen implements ASTVisitor { private void getCommonTPHS(TPHExtractor tphExtractor) { // Gemeinsame TPHs - ArrayList cTPHs = new ArrayList<>(); + ArrayList cTPHs = new ArrayList<>(); // Alle TPHs der Felder speichern - for(TypePlaceholder tph : tphExtractor.allTPHS.keySet()) { + for(String tph : tphExtractor.allTPHS.keySet()) { if(!tphExtractor.allTPHS.get(tph)) cTPHs.add(tph); } diff --git a/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java b/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java index c100eb4a..36753138 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java @@ -5,7 +5,11 @@ package de.dhbwstuttgart.bytecode; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; @@ -13,11 +17,15 @@ import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation; import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH; import de.dhbwstuttgart.syntaxtree.AbstractASTWalker; import de.dhbwstuttgart.syntaxtree.Constructor; +import de.dhbwstuttgart.syntaxtree.Field; import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.statement.LocalVar; import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl; +import de.dhbwstuttgart.syntaxtree.type.GenericRefType; +import de.dhbwstuttgart.syntaxtree.type.RefType; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.result.GenericInsertPair; import de.dhbwstuttgart.typeinference.result.ResultSet; @@ -29,7 +37,7 @@ import de.dhbwstuttgart.typeinference.result.ResultSet; public class TPHExtractor extends AbstractASTWalker { // Alle TPHs der Felder werden iKopf der Klasse definiert // alle TPHs der Klasse: (TPH, is in Method?) - final HashMap allTPHS = new HashMap<>(); + final HashMap allTPHS = new HashMap<>(); MethodAndTPH methodAndTph; Boolean inMethod = false; @@ -58,19 +66,79 @@ public class TPHExtractor extends AbstractASTWalker { methodAndTph.getLocalTphs().add(resolvedTPH.getName()); } - allTPHS.put(resolvedTPH, inMethod); + allTPHS.put(resolvedTPH.getName(), inMethod); +// final List cons = new ArrayList<>(); +// resultSet.resolveType(tph).additionalGenerics.forEach(ag -> { +// TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS); +// cons.add(con); +// }); +// +// Map visitMap = new HashMap<>(); +// for(TPHConstraint cc : cons) { +// visitMap.put(cc, false); +// } +// +// String left = resolvedTPH.getName(); +// for (TPHConstraint cc : visitMap.keySet()) { +// +// if(visitMap.get(cc)) +// continue; +// +// if (cc.getLeft().equals(left)) { +// allCons.add(cc); +// List toVisit = getToVisitCons(cons,cc.getRight(), visitMap); +// } +// } + 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) methodAndTph.getPairs().add(ag); allPairs.add(ag); TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS); - allCons.add(con); - } + if(!containsConstraint(allCons,con)) + allCons.add(con); +// } }); + } else if (resultSet.resolveType(tph).resolvedType instanceof RefType) { + RefType rt = (RefType) resultSet.resolveType(tph).resolvedType; + rt.accept(this); } } + private static boolean containsConstraint(ArrayList allCons, TPHConstraint c) { + for(TPHConstraint con:allCons) { + if(c.getLeft().equals(con.getLeft()) && c.getRight().equals(c.getRight())) { + return true; + } + } + return false; + } + + private List getToVisitCons(List cons, String right, Map visitMap) { + List res = new ArrayList<>(); + for(TPHConstraint cc : cons) { + if(cc.getLeft().equals(right)) { + res.add(cc); + if(visitMap.get(cc)) + visitMap.replace(cc, false); + } + } + return res; + } + + @Override + public void visit(GenericRefType genericRefType) { + String name = genericRefType.getParsedName(); + if (inMethod) { + methodAndTph.getLocalTphs().add(name); + if (inLocalOrParam) + methodAndTph.getLocalTphs().add(name); + } + allTPHS.put(name, inMethod); + } + private boolean contains(ArrayList pairs, GenericInsertPair genPair) { for (int i = 0; i < pairs.size(); ++i) { GenericInsertPair p = pairs.get(i); diff --git a/src/main/java/de/dhbwstuttgart/bytecode/signature/Signature.java b/src/main/java/de/dhbwstuttgart/bytecode/signature/Signature.java index ca191b7d..c3891a61 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/signature/Signature.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/signature/Signature.java @@ -41,11 +41,11 @@ public class Signature { private ResultSet resultSet; private ArrayList commonPairs; private HashMap> methodConstraints; - private ArrayList tphsClass; + private ArrayList tphsClass; private ArrayList consClass; public Signature(ClassOrInterface classOrInterface, HashMap genericsAndBounds, - ArrayList commonPairs, ArrayList tphsClass, ArrayList consClass) { + ArrayList commonPairs, ArrayList tphsClass, ArrayList consClass) { this.classOrInterface = classOrInterface; this.genericsAndBounds = genericsAndBounds; this.commonPairs = commonPairs; diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java index 89b55efb..2a4a3bd2 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java @@ -19,7 +19,7 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; public class Simplify { public static HashMap> simplifyConstraints(String name, TPHExtractor tphExtractor, - ArrayList tphsClass) { + ArrayList tphsClass) { // 1. check if there are any simple cycles like L set L=R and: // * remove both constraints @@ -38,8 +38,10 @@ public class Simplify { ArrayList allCons = new ArrayList<>(); for(TPHConstraint c : tphExtractor.allCons) { - TPHConstraint nc = new TPHConstraint(c.getLeft(), c.getRight(), c.getRel()); - allCons.add(nc); + if(!containsConstraint(allCons,c)) { + TPHConstraint nc = new TPHConstraint(c.getLeft(), c.getRight(), c.getRel()); + allCons.add(nc); + } } ArrayList consToRemove = new ArrayList<>(); @@ -382,7 +384,7 @@ public class Simplify { if (!containTPH(methodTphs, superTphRes)) { HashSet equals = getEqualsTphsFromEqualCons(eqCons, superTphRes); - if (classTPHSContainsTPH(tphsClass, superTphRes)) { + if (tphsClass.contains(superTphRes)/*classTPHSContainsTPH(tphsClass, superTphRes)*/) { result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals); } else { result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), @@ -450,6 +452,15 @@ public class Simplify { return result; } + private static boolean containsConstraint(ArrayList allCons, TPHConstraint c) { + for(TPHConstraint con:allCons) { + if(c.getLeft().equals(con.getLeft()) && c.getRight().equals(c.getRight())) { + return true; + } + } + return false; + } + private static void updateEqualCons(Map> replRes, ArrayList eqCons) { List oldNames = replRes.values().iterator().next(); String newName = replRes.keySet().iterator().next(); @@ -463,7 +474,7 @@ public class Simplify { } public static HashMap> simplifyConstraintsClass(TPHExtractor tphExtractor, - ArrayList tphsClass) { + ArrayList tphsClass) { // all constraints that will be simplified ArrayList allCons = tphExtractor.allCons; ArrayList consToRemove = new ArrayList<>(); @@ -627,7 +638,9 @@ public class Simplify { if (isTPHInConstraint(result, sub)) continue; - if (!classTPHSContainsTPH(tphsClass, sub)) +// if (!classTPHSContainsTPH(tphsClass, sub)) +// continue; + if (!tphsClass.contains(sub)) continue; if (numOfVisitedPairs >= size) @@ -656,7 +669,7 @@ public class Simplify { // add X at the beginning of the list. while (subAndSuper.containsValue(subTphRes)) { for (String tph : subAndSuper.keySet()) { - if (classTPHSContainsTPH(tphsClass, tph) && subAndSuper.get(tph).equals(subTphRes)) { + if (/*classTPHSContainsTPH(tphsClass, tph)*/tphsClass.contains(tph) && subAndSuper.get(tph).equals(subTphRes)) { subTphRes = tph; break; } diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/SimplifyResult.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/SimplifyResult.java index 96feb4dc..6517c2bc 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/SimplifyResult.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/SimplifyResult.java @@ -16,10 +16,10 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; */ public class SimplifyResult { private final ArrayList classConstraints; - private final ArrayList tphsClass; + private final ArrayList tphsClass; private final HashMap>> methodsConstraints; - public SimplifyResult(ArrayList classConstraints, ArrayList tphsClass, + public SimplifyResult(ArrayList classConstraints, ArrayList tphsClass, HashMap>> methodsConstraints) { super(); this.classConstraints = classConstraints; @@ -35,7 +35,7 @@ public class SimplifyResult { return methodsConstraints; } - public ArrayList getTphsClass() { + public ArrayList getTphsClass() { return tphsClass; } diff --git a/src/test/java/bytecode/ClassGenLamTest.java b/src/test/java/bytecode/ClassGenLamTest.java new file mode 100644 index 00000000..33b9ee76 --- /dev/null +++ b/src/test/java/bytecode/ClassGenLamTest.java @@ -0,0 +1,37 @@ +package bytecode; + +import static org.junit.Assert.*; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; + +import org.junit.BeforeClass; +import org.junit.Test; + +import de.dhbwstuttgart.core.JavaTXCompiler; + +public class ClassGenLamTest { + + private static String path; + private static File fileToTest; + private static JavaTXCompiler compiler; + private static ClassLoader loader; + private static Class classToTest; + private static String pathToClassFile; + private static Object instanceOfClass; + + @Test + public void generateBC() throws Exception { + path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/ClassGenLam.jav"; + fileToTest = new File(path); + compiler = new JavaTXCompiler(fileToTest); + pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"; + compiler.generateBytecode(pathToClassFile); + loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); + classToTest = loader.loadClass("ClassGenLam"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + } + +} diff --git a/src/test/resources/bytecode/javFiles/ClassGenLam.jav b/src/test/resources/bytecode/javFiles/ClassGenLam.jav new file mode 100644 index 00000000..0e9cf050 --- /dev/null +++ b/src/test/resources/bytecode/javFiles/ClassGenLam.jav @@ -0,0 +1,8 @@ +import java.lang.Integer; + +public class ClassGenLam { + lam = x-> x; +// public ClassGenLam() { +// lam = x->x; +// } +} \ No newline at end of file