Merge remote-tracking branch 'origin/bytecode2' into bytecode2

This commit is contained in:
Michael Uhl 2019-02-24 15:06:49 +01:00
commit 86768153c0
7 changed files with 700 additions and 517 deletions

View File

@ -5,6 +5,7 @@ package de.dhbwstuttgart.bytecode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
@ -12,7 +13,11 @@ 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.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.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
import de.dhbwstuttgart.typeinference.result.ResultSet;
@ -26,7 +31,10 @@ public class TPHExtractor extends AbstractASTWalker{
// alle TPHs der Klasse: (TPH, is in Method?)
final HashMap<TypePlaceholder, Boolean> allTPHS = new HashMap<>();
MethodAndTPH methodAndTph;
Boolean inMethod = false;
boolean inLocalOrParam = false;
public final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
final ArrayList<GenericInsertPair> allPairs = new ArrayList<>();
public final ArrayList<TPHConstraint> allCons = new ArrayList<>();
@ -44,8 +52,11 @@ public class TPHExtractor extends AbstractASTWalker{
public void visit(TypePlaceholder tph) {
if (resultSet.resolveType(tph).resolvedType instanceof TypePlaceholder) {
TypePlaceholder resolvedTPH = (TypePlaceholder) resultSet.resolveType(tph).resolvedType;
if(inMethod)
if (inMethod) {
methodAndTph.getTphs().add(resolvedTPH.getName());
if (inLocalOrParam)
methodAndTph.getLocalTphs().add(resolvedTPH.getName());
}
allTPHS.put(resolvedTPH, inMethod);
resultSet.resolveType(tph).additionalGenerics.forEach(ag -> {
@ -59,6 +70,7 @@ public class TPHExtractor extends AbstractASTWalker{
});
}
}
private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) {
for (int i = 0; i < pairs.size(); ++i) {
GenericInsertPair p = pairs.get(i);
@ -67,6 +79,7 @@ public class TPHExtractor extends AbstractASTWalker{
}
return false;
}
@Override
public void visit(Method method) {
inMethod = true;
@ -83,4 +96,25 @@ public class TPHExtractor extends AbstractASTWalker{
inMethod = true;
}
@Override
public void visit(LocalVarDecl localVarDecl) {
inLocalOrParam = true;
super.visit(localVarDecl);
inLocalOrParam = false;
}
@Override
public void visit(LocalVar localVar) {
inLocalOrParam = true;
super.visit(localVar);
inLocalOrParam = false;
}
@Override
public void visit(ParameterList formalParameters) {
inLocalOrParam = true;
super.visit(formalParameters);
inLocalOrParam = false;
}
}

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
public class ConstraintsFinder {
private List<TPHConstraint> allConstaints;
@ -18,11 +19,13 @@ public class ConstraintsFinder {
List<TPHConstraint> visitedCons = new ArrayList<>();
for(TPHConstraint c : allConstaints) {
if(c.getRel() == Relation.EXTENDS) {
// get constraints with the same left side
List<TPHConstraint> cons = getConstraints(c,visitedCons);
if(cons.size()>1)
result.add(cons);
}
}
return result;
}

View File

@ -10,6 +10,8 @@ public class MethodAndTPH {
private String name;
private final ArrayList<String> tphs = new ArrayList<>();
private final ArrayList<GenericInsertPair> pairs = new ArrayList<>();
// tphs of local variables and parameters
private final ArrayList<String> localTphs = new ArrayList<>();
public MethodAndTPH(String name) {
this.name = name;
@ -26,4 +28,9 @@ public class MethodAndTPH {
public String getName() {
return name;
}
public ArrayList<String> getLocalTphs() {
return localTphs;
}
}

View File

@ -12,12 +12,14 @@ public class NameReplacer {
private List<TPHConstraint> constraints;
private List<TPHConstraint> allConstraints;
private List<String> tphs;
private List<String> localTphs;
public NameReplacer(List<TPHConstraint> constraints, List<TPHConstraint> allConstraints,List<String> tphs) {
public NameReplacer(List<TPHConstraint> constraints, List<TPHConstraint> allConstraints,List<String> tphs, ArrayList<String> localTphs) {
super();
this.constraints = constraints;
this.allConstraints = allConstraints;
this.tphs = tphs;
this.localTphs = localTphs;
}
public Map<String, List<String>> replaceNames() {
@ -34,8 +36,11 @@ public class NameReplacer {
if(names.contains(cons.getRight()))
cons.setRight(newName);
}
tphs.removeAll(names);
tphs.add(newName);
localTphs.removeAll(names);
localTphs.add(newName);
HashMap<String, List<String>> res = new HashMap<>();
res.put(newName, names);

View File

@ -18,13 +18,15 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class Simplify {
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor, ArrayList<TypePlaceholder> tphsClass) {
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor,
ArrayList<TypePlaceholder> tphsClass) {
// 1. check if there are any simple cycles like L<R and R<L:
// a) yes => set L=R and:
// * remove both constraints
// * substitute L with R in all constraint
// b)no => go to next step
// 2. check the result of step 1 if there are any equal-constraints like L=R, M=R ..
// 2. check the result of step 1 if there are any equal-constraints like L=R,
// M=R ..
// a) yes => put all such TPhs in a map and define "key-Cons"
// -- key-Cons = TPH < Object --
// put this Constraint and the
@ -32,9 +34,26 @@ public class Simplify {
// 3. is
// all constraints that will be simplified
ArrayList<TPHConstraint> allCons = tphExtractor.allCons;
// ArrayList<TPHConstraint> allCons = tphExtractor.allCons;
ArrayList<TPHConstraint> allCons = new ArrayList<>();
for(TPHConstraint c : tphExtractor.allCons) {
TPHConstraint nc = new TPHConstraint(c.getLeft(), c.getRight(), c.getRel());
allCons.add(nc);
}
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
// get all tph of the method
ArrayList<String> methodTphs = new ArrayList<>();
ArrayList<String> localTphs = new ArrayList<>();
for (MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
if (m.getName().equals(name)) {
methodTphs = m.getTphs();
localTphs = m.getLocalTphs();
break;
}
}
// step 1:
for (TPHConstraint c : allCons) {
@ -135,7 +154,8 @@ public class Simplify {
eq.add(t);
}
// generate a new constraint (left < Object)
TPHConstraint constraint = new ExtendsConstraint(left, Type.getInternalName(Object.class), Relation.EXTENDS);
TPHConstraint constraint = new ExtendsConstraint(left, Type.getInternalName(Object.class),
Relation.EXTENDS);
// put the generated constraint and its equal set into result set
result.put(constraint, eq);
constraints.clear();
@ -143,23 +163,36 @@ public class Simplify {
allTypes.clear();
}
}
for (TPHConstraint ec : allCons) {
if(ec.getRel() == Relation.EQUAL) {
if(!localTphs.contains(ec.getRight())) {
localTphs.add(ec.getRight());
}
if(!methodTphs.contains(ec.getRight())) {
methodTphs.add(ec.getRight());
}
}
}
// build an equal set that contains all types
// which are equal and for each equal constraint put left side and right side
// in this set Then generate a constraint type < Object and put it
// with the equal set into the result.
for(TPHConstraint c : allCons) {
if(c.getRel()==Relation.EQUAL) {
if(!isTPHInResEqual(result, c.getLeft())) {
HashSet<String> equalTPHs = getEqualsTPHs(result, c);
TPHConstraint constraint = getKeyConstraint(result,c);
equalTPHs.add(c.getLeft());
equalTPHs.add(c.getRight());
result.put(constraint, equalTPHs);
}
consToRemove.add(c);
size--;
}
}
// for(TPHConstraint c : allCons) {
// if(c.getRel()==Relation.EQUAL) {
// if(!isTPHInResEqual(result, c.getLeft())) {
// HashSet<String> equalTPHs = getEqualsTPHs(result, c);
// TPHConstraint constraint = getKeyConstraint(result,c);
// equalTPHs.add(c.getLeft());
// equalTPHs.add(c.getRight());
// result.put(constraint, equalTPHs);
// }
// consToRemove.add(c);
// size--;
// }
// }
System.out.println("Step 2 Result: ");
result.forEach((c, hs) -> {
@ -170,17 +203,14 @@ public class Simplify {
System.out.println();
});
System.out.println("----------------");
// remove all equal-constraints
allCons.removeAll(consToRemove);
// add all generated constraints to allCons
allCons.addAll(result.keySet());
if (!allCons.isEmpty() && allCons.size() < 2) {
TPHConstraint cons = allCons.get(0);
if (!result.containsKey(cons)) {
result.put(cons, null);
if (!cons.getRight().equals(Type.getInternalName(Object.class)))
result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS), null);
result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class),
Relation.EXTENDS), null);
}
return result;
@ -193,14 +223,7 @@ public class Simplify {
if (c.getRight().equals(Type.getInternalName(Object.class)))
size--;
}
// get all tph of the method
ArrayList<String> methodTphs = new ArrayList<>();
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
if(m.getName().equals(name)) {
methodTphs = m.getTphs();
break;
}
}
// finder looks for constraints that have the same left hand side
// and put them in a list
ConstraintsFinder finder = new ConstraintsFinder(allCons);
@ -211,7 +234,7 @@ public class Simplify {
for (List<TPHConstraint> list : foundCons) {
// generate a new name and replace the right hand side for each constraint
// in list with the new name
NameReplacer replacer = new NameReplacer(list,allCons,methodTphs);
NameReplacer replacer = new NameReplacer(list, allCons, methodTphs, localTphs);
// new name -> [all old names]
Map<String, List<String>> replRes = replacer.replaceNames();
// create an equal constraint for each value in repres
@ -220,7 +243,11 @@ public class Simplify {
EqualConstraint ec = new EqualConstraint(val, key, Relation.EQUAL);
eqCons.add(ec);
}
for (TPHConstraint c : allCons) {
if (c.getRel() == Relation.EQUAL && key.equals(c.getRight())) {
eqCons.add(c);
}
}
updateEqualCons(replRes, eqCons);
TPHConstraint c = list.get(0);
@ -275,9 +302,24 @@ public class Simplify {
HashMap<String, String> subAndSuper = new HashMap<>();
for (TPHConstraint c : allCons) {
if (c.getRel() == Relation.EXTENDS)
subAndSuper.put(c.getLeft(), c.getRight());
}
for (TPHConstraint ec : allCons) {
if(ec.getRel() == Relation.EQUAL) {
methodTphs.remove(ec.getLeft());
localTphs.remove(ec.getLeft());
if(!localTphs.contains(ec.getRight())) {
localTphs.add(ec.getRight());
}
if(!methodTphs.contains(ec.getRight())) {
methodTphs.add(ec.getRight());
}
}
}
int numOfVisitedPairs = 0;
for (String sub : subAndSuper.keySet()) {
if (isTPHInConstraint(result, sub))
@ -294,7 +336,7 @@ public class Simplify {
tphInRel.add(superT);
numOfVisitedPairs++;
while(subAndSuper.containsKey(superT)) {
while (!localTphs.contains(superT) && subAndSuper.containsKey(superT)) {
superT = subAndSuper.get(superT);
if (tphInRel.contains(superT)) {
break;
@ -310,7 +352,7 @@ public class Simplify {
// if there is any constraint X < subTph, then
// add X at the beginning of the list.
while(subAndSuper.containsValue(subTphRes)) {
while (!localTphs.contains(subTphRes) && subAndSuper.containsValue(subTphRes)) {
for (String tph : subAndSuper.keySet()) {
if (containTPH(methodTphs, tph) && subAndSuper.get(tph).equals(subTphRes)) {
subTphRes = tph;
@ -343,7 +385,8 @@ public class Simplify {
if (classTPHSContainsTPH(tphsClass, superTphRes)) {
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals);
} else {
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), equals);
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS),
equals);
}
} else {
@ -351,18 +394,43 @@ public class Simplify {
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals);
if (!isTPHInConstraint(result, superTphRes) && !isTphInEqualSet(result, superTphRes)) {
HashSet<String> equals2 = getEqualsTphsFromEqualCons(eqCons, superTphRes);
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), equals2);
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS),
equals2);
}
}
}
for(String tph : methodTphs) {
// for(String tph : methodTphs) {
for (String tph : localTphs) {
if (!isTPHInConstraint(result, tph) && !isTphInEqualSet(result, tph)) {
HashSet<String> equals = getEqualsTphsFromEqualCons(eqCons, tph);
result.put(new ExtendsConstraint(tph, Type.getInternalName(Object.class), Relation.EXTENDS), equals);
}
}
// build an equal set that contains all types
// which are equal and for each equal constraint put left side and right side
// in this set Then generate a constraint type < Object and put it
// with the equal set into the result.
for (TPHConstraint c : allCons) {
if (c.getRel() == Relation.EQUAL) {
if (!isTPHInResEqual(result, c.getLeft())) {
HashSet<String> equalTPHs = getEqualsTPHs(result, c);
TPHConstraint constraint = getKeyConstraint(result, c);
equalTPHs.add(c.getLeft());
equalTPHs.add(c.getRight());
result.put(constraint, equalTPHs);
}
consToRemove.add(c);
size--;
}
}
// remove all equal-constraints
allCons.removeAll(consToRemove);
// add all generated constraints to allCons
allCons.addAll(result.keySet());
System.out.println("EndResult: ");
result.forEach((c, hs) -> {
if (c != null) {
@ -376,14 +444,12 @@ public class Simplify {
}
}
System.out.println();
});
System.out.println("----------------");
return result;
}
private static void updateEqualCons(Map<String, List<String>> replRes, ArrayList<TPHConstraint> eqCons) {
List<String> oldNames = replRes.values().iterator().next();
String newName = replRes.keySet().iterator().next();
@ -396,8 +462,8 @@ public class Simplify {
}
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraintsClass(TPHExtractor tphExtractor, ArrayList<TypePlaceholder> tphsClass) {
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraintsClass(TPHExtractor tphExtractor,
ArrayList<TypePlaceholder> tphsClass) {
// all constraints that will be simplified
ArrayList<TPHConstraint> allCons = tphExtractor.allCons;
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
@ -421,7 +487,6 @@ public class Simplify {
}
}
allCons.removeAll(consToRemove);
consToRemove = new ArrayList<>();
@ -496,7 +561,8 @@ public class Simplify {
eq.add(t);
}
// generate a new constraint (left < Object)
TPHConstraint constraint = new ExtendsConstraint(left, Type.getInternalName(Object.class), Relation.EXTENDS);
TPHConstraint constraint = new ExtendsConstraint(left, Type.getInternalName(Object.class),
Relation.EXTENDS);
// put the generated constraint and its equal set into result set
result.put(constraint, eq);
constraints.clear();
@ -531,7 +597,8 @@ public class Simplify {
TPHConstraint cons = allCons.get(0);
if (!result.containsKey(cons)) {
result.put(cons, null);
result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS), null);
result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS),
null);
}
return result;
@ -607,8 +674,6 @@ public class Simplify {
subTphRes = tphInRel.getFirst();
HashSet<String> equals = getEqualsTphsFromEqualCons(eqCons, superTphRes);
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals);
@ -627,14 +692,12 @@ public class Simplify {
}
}
System.out.println();
});
System.out.println("----------------");
return result;
}
private static boolean classTPHSContainsTPH(ArrayList<TypePlaceholder> tphsClass, String superTphRes) {
for (TypePlaceholder tph : tphsClass) {
if (tph.getName().equals(superTphRes))
@ -662,8 +725,8 @@ public class Simplify {
return ee;
}
private static void substituteInMap(HashMap<String, String> subAndSuper, ArrayList<TPHConstraint> allCons,ArrayList<TPHConstraint> eqCons, String toSubs,
String tph) {
private static void substituteInMap(HashMap<String, String> subAndSuper, ArrayList<TPHConstraint> allCons,
ArrayList<TPHConstraint> eqCons, String toSubs, String tph) {
substituteTPH(allCons, toSubs, tph);
if (subAndSuper.containsKey(toSubs) && subAndSuper.containsKey(tph)) {
toSubs = subAndSuper.remove(toSubs);
@ -718,13 +781,15 @@ public class Simplify {
}
}
public static HashMap<TPHConstraint, HashSet<String>> simplifyContraints(HashMap<TPHConstraint, HashSet<String>> allConstraints) {
public static HashMap<TPHConstraint, HashSet<String>> simplifyContraints(
HashMap<TPHConstraint, HashSet<String>> allConstraints) {
// 1. check if there are any cycles like L<R and R<L:
// a) yes => set L=R and:
// * remove both constraints
// * substitute L with R in all constraint
// b)no => go to next step
// 2. check the result of step 1 if there are any equal-constraints like L=R, M=R ..
// 2. check the result of step 1 if there are any equal-constraints like L=R,
// M=R ..
// a) yes => put all such TPhs in a map and define "key-Cons"
// -- key-Cons = TPH < Object --
// put this Constraint and the
@ -858,10 +923,12 @@ public class Simplify {
i++;
}
if (superTphRes.equals(Type.getInternalName(Object.class))) {
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS),
null);
} else {
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), null);
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS),
null);
}
}
@ -878,7 +945,6 @@ public class Simplify {
}
}
System.out.println();
});
System.out.println("----------------");
@ -921,11 +987,29 @@ public class Simplify {
return false;
}
private static TPHConstraint getKeyConstraint(HashMap<TPHConstraint, HashSet<String>> result, TPHConstraint toFind) {
private static TPHConstraint getKeyConstraint(HashMap<TPHConstraint, HashSet<String>> result, TPHConstraint toFind,
ArrayList<TPHConstraint> allCons) {
for (TPHConstraint c : result.keySet()) {
if (c.containTPH(toFind.getLeft()))
return c;
}
for (TPHConstraint c : allCons) {
if (toFind.getRight().equals(c.getLeft()))
return c;
}
return new ExtendsConstraint(toFind.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS);
}
private static TPHConstraint getKeyConstraint(HashMap<TPHConstraint, HashSet<String>> result,
TPHConstraint toFind) {
for (TPHConstraint c : result.keySet()) {
if (c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight()))
return c;
}
return new ExtendsConstraint(toFind.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS);
}

View File

@ -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 KompTphTest {
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/KompTph.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("KompTph");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
}

View File

@ -0,0 +1,13 @@
public class KompTph {
public m(a, b, c) {
var d = a;
var e = a;
a = b;
c = b;
m2(a,c);
}
public m2(a,b){
m(a,a,b);
}
}