Generics beruecksichtigt

This commit is contained in:
Fayez Abu Alia 2019-04-11 11:26:54 +02:00
parent 9d16855ce2
commit 602216d9e2
7 changed files with 169 additions and 30 deletions

View File

@ -64,7 +64,7 @@ public class BytecodeGen implements ASTVisitor {
private String superClass; private String superClass;
private ArrayList<TypePlaceholder> tphsClass; private ArrayList<String> tphsClass;
// stores parameter, local vars and the next index on the local variable table, which use for aload_i, astore_i,... // stores parameter, local vars and the next index on the local variable table, which use for aload_i, astore_i,...
HashMap<String, Integer> paramsAndLocals = new HashMap<>(); HashMap<String, Integer> paramsAndLocals = new HashMap<>();
@ -156,7 +156,7 @@ public class BytecodeGen implements ASTVisitor {
getCommonTPHS(tphExtractor); getCommonTPHS(tphExtractor);
tphsClass = new ArrayList<>(); tphsClass = new ArrayList<>();
for(TypePlaceholder t : tphExtractor.allTPHS.keySet()) { for(String t : tphExtractor.allTPHS.keySet()) {
if(!tphExtractor.allTPHS.get(t)) if(!tphExtractor.allTPHS.get(t))
tphsClass.add(t); tphsClass.add(t);
} }
@ -172,19 +172,32 @@ public class BytecodeGen implements ASTVisitor {
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraintsClass(tphExtractor,tphsClass); HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraintsClass(tphExtractor,tphsClass);
ArrayList<TPHConstraint> consClass = new ArrayList<>(); ArrayList<TPHConstraint> consClass = new ArrayList<>();
for(TPHConstraint cons : constraints.keySet()) { for(TPHConstraint cons : constraints.keySet()) {
TypePlaceholder right = null; String right = null;
for(TypePlaceholder tph : tphsClass) { boolean isToAdd = false;
if(cons.getLeft().equals(tph.getName())) { for(String tph : tphsClass) {
if(cons.getLeft().equals(tph)) {
consClass.add(cons); 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); tphsClass.add(right);
removeFromMethod(right.getName()); removeFromMethod(right);
right = null; right = null;
isToAdd= false;
} }
// if(right != null) {
// tphsClass.add(right);
// removeFromMethod(right);
// right = null;
// }
} }
SimplifyResult sRes = new SimplifyResult(consClass, tphsClass, new HashMap<>()); SimplifyResult sRes = new SimplifyResult(consClass, tphsClass, new HashMap<>());
@ -239,9 +252,9 @@ public class BytecodeGen implements ASTVisitor {
} }
private TypePlaceholder getTPH(String name) { private String getTPH(String name) {
for(TypePlaceholder tph: tphExtractor.allTPHS.keySet()) { for(String tph: tphExtractor.allTPHS.keySet()) {
if(tph.getName().equals(name)) if(tph.equals(name))
return tph; return tph;
} }
throw new NoSuchElementException("TPH "+name +" does not exist"); throw new NoSuchElementException("TPH "+name +" does not exist");
@ -249,9 +262,9 @@ public class BytecodeGen implements ASTVisitor {
private void getCommonTPHS(TPHExtractor tphExtractor) { private void getCommonTPHS(TPHExtractor tphExtractor) {
// Gemeinsame TPHs // Gemeinsame TPHs
ArrayList<TypePlaceholder> cTPHs = new ArrayList<>(); ArrayList<String> cTPHs = new ArrayList<>();
// Alle TPHs der Felder speichern // Alle TPHs der Felder speichern
for(TypePlaceholder tph : tphExtractor.allTPHS.keySet()) { for(String tph : tphExtractor.allTPHS.keySet()) {
if(!tphExtractor.allTPHS.get(tph)) if(!tphExtractor.allTPHS.get(tph))
cTPHs.add(tph); cTPHs.add(tph);
} }

View File

@ -5,7 +5,11 @@ package de.dhbwstuttgart.bytecode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; 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.ExtendsConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; 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.bytecode.utilities.MethodAndTPH;
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker; import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
import de.dhbwstuttgart.syntaxtree.Constructor; import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.Field;
import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.statement.LocalVar; import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl; 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.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.GenericInsertPair; import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
@ -29,7 +37,7 @@ import de.dhbwstuttgart.typeinference.result.ResultSet;
public class TPHExtractor extends AbstractASTWalker { public class TPHExtractor extends AbstractASTWalker {
// Alle TPHs der Felder werden iKopf der Klasse definiert // Alle TPHs der Felder werden iKopf der Klasse definiert
// alle TPHs der Klasse: (TPH, is in Method?) // alle TPHs der Klasse: (TPH, is in Method?)
final HashMap<TypePlaceholder, Boolean> allTPHS = new HashMap<>(); final HashMap<String, Boolean> allTPHS = new HashMap<>();
MethodAndTPH methodAndTph; MethodAndTPH methodAndTph;
Boolean inMethod = false; Boolean inMethod = false;
@ -58,19 +66,79 @@ public class TPHExtractor extends AbstractASTWalker {
methodAndTph.getLocalTphs().add(resolvedTPH.getName()); methodAndTph.getLocalTphs().add(resolvedTPH.getName());
} }
allTPHS.put(resolvedTPH, inMethod); allTPHS.put(resolvedTPH.getName(), inMethod);
// final List<TPHConstraint> 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<TPHConstraint, Boolean> 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<TPHConstraint> toVisit = getToVisitCons(cons,cc.getRight(), visitMap);
// }
// }
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)
methodAndTph.getPairs().add(ag); methodAndTph.getPairs().add(ag);
allPairs.add(ag); allPairs.add(ag);
TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS); 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<TPHConstraint> allCons, TPHConstraint c) {
for(TPHConstraint con:allCons) {
if(c.getLeft().equals(con.getLeft()) && c.getRight().equals(c.getRight())) {
return true;
}
}
return false;
}
private List<TPHConstraint> getToVisitCons(List<TPHConstraint> cons, String right, Map<TPHConstraint, Boolean> visitMap) {
List<TPHConstraint> 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<GenericInsertPair> pairs, GenericInsertPair genPair) { private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) {
for (int i = 0; i < pairs.size(); ++i) { for (int i = 0; i < pairs.size(); ++i) {
GenericInsertPair p = pairs.get(i); GenericInsertPair p = pairs.get(i);

View File

@ -41,11 +41,11 @@ public class Signature {
private ResultSet resultSet; private ResultSet resultSet;
private ArrayList<GenericInsertPair> commonPairs; private ArrayList<GenericInsertPair> commonPairs;
private HashMap<TPHConstraint,HashSet<String>> methodConstraints; private HashMap<TPHConstraint,HashSet<String>> methodConstraints;
private ArrayList<TypePlaceholder> tphsClass; private ArrayList<String> tphsClass;
private ArrayList<TPHConstraint> consClass; private ArrayList<TPHConstraint> consClass;
public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds, public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds,
ArrayList<GenericInsertPair> commonPairs, ArrayList<TypePlaceholder> tphsClass, ArrayList<TPHConstraint> consClass) { ArrayList<GenericInsertPair> commonPairs, ArrayList<String> tphsClass, ArrayList<TPHConstraint> consClass) {
this.classOrInterface = classOrInterface; this.classOrInterface = classOrInterface;
this.genericsAndBounds = genericsAndBounds; this.genericsAndBounds = genericsAndBounds;
this.commonPairs = commonPairs; this.commonPairs = commonPairs;

View File

@ -19,7 +19,7 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class Simplify { public class Simplify {
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor, public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor,
ArrayList<TypePlaceholder> tphsClass) { ArrayList<String> tphsClass) {
// 1. check if there are any simple cycles like L<R and R<L: // 1. check if there are any simple cycles like L<R and R<L:
// a) yes => set L=R and: // a) yes => set L=R and:
// * remove both constraints // * remove both constraints
@ -38,8 +38,10 @@ public class Simplify {
ArrayList<TPHConstraint> allCons = new ArrayList<>(); ArrayList<TPHConstraint> allCons = new ArrayList<>();
for(TPHConstraint c : tphExtractor.allCons) { for(TPHConstraint c : tphExtractor.allCons) {
TPHConstraint nc = new TPHConstraint(c.getLeft(), c.getRight(), c.getRel()); if(!containsConstraint(allCons,c)) {
allCons.add(nc); TPHConstraint nc = new TPHConstraint(c.getLeft(), c.getRight(), c.getRel());
allCons.add(nc);
}
} }
ArrayList<TPHConstraint> consToRemove = new ArrayList<>(); ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
@ -382,7 +384,7 @@ public class Simplify {
if (!containTPH(methodTphs, superTphRes)) { if (!containTPH(methodTphs, superTphRes)) {
HashSet<String> equals = getEqualsTphsFromEqualCons(eqCons, superTphRes); HashSet<String> equals = getEqualsTphsFromEqualCons(eqCons, superTphRes);
if (classTPHSContainsTPH(tphsClass, superTphRes)) { if (tphsClass.contains(superTphRes)/*classTPHSContainsTPH(tphsClass, superTphRes)*/) {
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals); result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals);
} else { } else {
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS),
@ -450,6 +452,15 @@ public class Simplify {
return result; return result;
} }
private static boolean containsConstraint(ArrayList<TPHConstraint> 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<String, List<String>> replRes, ArrayList<TPHConstraint> eqCons) { private static void updateEqualCons(Map<String, List<String>> replRes, ArrayList<TPHConstraint> eqCons) {
List<String> oldNames = replRes.values().iterator().next(); List<String> oldNames = replRes.values().iterator().next();
String newName = replRes.keySet().iterator().next(); String newName = replRes.keySet().iterator().next();
@ -463,7 +474,7 @@ public class Simplify {
} }
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraintsClass(TPHExtractor tphExtractor, public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraintsClass(TPHExtractor tphExtractor,
ArrayList<TypePlaceholder> tphsClass) { ArrayList<String> tphsClass) {
// all constraints that will be simplified // all constraints that will be simplified
ArrayList<TPHConstraint> allCons = tphExtractor.allCons; ArrayList<TPHConstraint> allCons = tphExtractor.allCons;
ArrayList<TPHConstraint> consToRemove = new ArrayList<>(); ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
@ -627,7 +638,9 @@ public class Simplify {
if (isTPHInConstraint(result, sub)) if (isTPHInConstraint(result, sub))
continue; continue;
if (!classTPHSContainsTPH(tphsClass, sub)) // if (!classTPHSContainsTPH(tphsClass, sub))
// continue;
if (!tphsClass.contains(sub))
continue; continue;
if (numOfVisitedPairs >= size) if (numOfVisitedPairs >= size)
@ -656,7 +669,7 @@ public class Simplify {
// add X at the beginning of the list. // add X at the beginning of the list.
while (subAndSuper.containsValue(subTphRes)) { while (subAndSuper.containsValue(subTphRes)) {
for (String tph : subAndSuper.keySet()) { 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; subTphRes = tph;
break; break;
} }

View File

@ -16,10 +16,10 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
*/ */
public class SimplifyResult { public class SimplifyResult {
private final ArrayList<TPHConstraint> classConstraints; private final ArrayList<TPHConstraint> classConstraints;
private final ArrayList<TypePlaceholder> tphsClass; private final ArrayList<String> tphsClass;
private final HashMap<String, HashMap<TPHConstraint, HashSet<String>>> methodsConstraints; private final HashMap<String, HashMap<TPHConstraint, HashSet<String>>> methodsConstraints;
public SimplifyResult(ArrayList<TPHConstraint> classConstraints, ArrayList<TypePlaceholder> tphsClass, public SimplifyResult(ArrayList<TPHConstraint> classConstraints, ArrayList<String> tphsClass,
HashMap<String, HashMap<TPHConstraint, HashSet<String>>> methodsConstraints) { HashMap<String, HashMap<TPHConstraint, HashSet<String>>> methodsConstraints) {
super(); super();
this.classConstraints = classConstraints; this.classConstraints = classConstraints;
@ -35,7 +35,7 @@ public class SimplifyResult {
return methodsConstraints; return methodsConstraints;
} }
public ArrayList<TypePlaceholder> getTphsClass() { public ArrayList<String> getTphsClass() {
return tphsClass; return tphsClass;
} }

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 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();
}
}

View File

@ -0,0 +1,8 @@
import java.lang.Integer;
public class ClassGenLam {
lam = x-> x;
// public ClassGenLam() {
// lam = x->x;
// }
}