Generics generator step 1

This commit is contained in:
Fayez Abu Alia 2019-07-10 15:26:16 +02:00
parent 4f39eccecb
commit d77f2176f2
11 changed files with 417 additions and 2 deletions

View File

@ -44,6 +44,10 @@ public class TPHConstraint {
return left.equals(tph)||right.equals(tph);
}
public boolean equalConstraint(TPHConstraint constraint) {
return rel == constraint.getRel() && left.equals(constraint.getLeft()) && right.equals(constraint.getRight());
}
@Override
public String toString() {
if(rel == Relation.EXTENDS) {

View File

@ -0,0 +1,76 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGenerator;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
/**
* @author fayez
*
*/
public class CyclesFinder {
private final List<TPHConstraint> allCons;
public CyclesFinder(List<TPHConstraint> allCons) {
this.allCons = allCons;
}
public List<SimpleCycle> findSimpleCycles() {
List<SimpleCycle> simpleCycles = new ArrayList<>();
allCons.forEach(c->{
String left = c.getLeft();
String right = c.getRight();
if (c.getRel() == Relation.EXTENDS && !containsInCycle(c,simpleCycles)) {
Optional<TPHConstraint> revCon = GenericsGeneratorUtility.getReverseConstraint(allCons, left, right);
if(revCon.isPresent()) {
TPHConstraint reverseConstraint = revCon.get();
SimpleCycle simpleCycle = new SimpleCycle(c, reverseConstraint);
simpleCycles.add(simpleCycle);
}
}
});
return simpleCycles;
}
private boolean containsInCycle(TPHConstraint c, List<SimpleCycle> simpleCycles) {
return simpleCycles.stream().filter(sc->{
return sc.contains(c);
}).count() > 0;
}
public List<LongCycle> findLongCycles() {
List<TPHConstraint> vistedConstraints = new ArrayList<>(allCons.size());
for(TPHConstraint constraint : allCons) {
vistedConstraints.add(constraint);
checkConstraint(constraint,vistedConstraints);
}
return null;
}
private void checkConstraint(TPHConstraint constraint, List<TPHConstraint> vistedConstraints) {
List<String> tphsInRelation = new LinkedList<>();
tphsInRelation.add(constraint.getLeft());
tphsInRelation.add(constraint.getRight());
for(TPHConstraint con : allCons) {
if(!vistedConstraints.contains(con)) {
String left = con.getLeft();
String right = con.getRight();
int lastIndex = tphsInRelation.size()-1;
if(left.equals(tphsInRelation.get(lastIndex))) {
tphsInRelation.add(right);
}
}
}
}
}

View File

@ -0,0 +1,50 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGenerator;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import de.dhbwstuttgart.bytecode.TPHExtractor;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.simplifyRes.GenericsGeneratorResult;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
import de.dhbwstuttgart.bytecode.utilities.MethodUtility;
import de.dhbwstuttgart.syntaxtree.Method;
/**
* @author fayez
*
*/
public class GenericsGenerator {
public static List<GenericsGeneratorResult> generateConstraintsForMethod(Method method, TPHExtractor tphExtractor,
List<String> tphsClass) {
List<TPHConstraint> allCons = tphExtractor.allCons;
String methodID = MethodUtility.createID(tphExtractor.getResolver(), method);
List<String> methodTPHS = GenericsGeneratorUtility.getMethodTPHS(methodID ,tphExtractor.ListOfMethodsAndTph);
List<TPHConstraint> consToRemove = new ArrayList<>();
CyclesFinder cyclesFinder = new CyclesFinder(allCons);
/* find all simple cycles if they are exist */
List<SimpleCycle> simpleCycles = cyclesFinder.findSimpleCycles();
if(!simpleCycles.isEmpty()) {
GenericsGeneratorUtility.modifyRelation(simpleCycles);
GenericsGeneratorUtility.removeAllReverseConstraints(allCons,simpleCycles);
GenericsGeneratorUtility.substituteTPH(allCons, simpleCycles);
}
/* find all long cycles */
List<LongCycle> longCycles = cyclesFinder.findLongCycles();
return null;
}
}

View File

@ -0,0 +1,76 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGenerator;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
/**
* @author fayez
*
*/
public class GenericsGeneratorUtility {
/**
* Returns a list of type placeholders names of a specified method
*
* @param methodID The id of the method ReturnTypeMethodName(ParameterTypes)
* @param listOfMethodsAndTph List of all methods
* @return a list of type placehoders names
*/
public static List<String> getMethodTPHS(String methodID, ArrayList<MethodAndTPH> listOfMethodsAndTph) {
return listOfMethodsAndTph.stream().filter(mt->mt.getId().equals(methodID)).findAny().get().getTphs();
}
/**
* Returns a reverse constraint of a specified constraint which is given by its left and right
* side
*
* @param allCons List of all constraints
* @param left The left side of the given constraint
* @param right The right side of the given constraint
* @return An Optional object which contains the reverse constraint if it is exist
*/
public static Optional<TPHConstraint> getReverseConstraint(List<TPHConstraint> allCons, String left, String right) {
return allCons.stream().filter(c->{
return c.getRight().equals(left) && c.getLeft().equals(right);
}).findAny();
}
/**
* Substitutes the old name by the new name in all constraints
*
* @param allCons List of all constraints
* @param oldName The name to be replaced
* @param newName The new name
*/
public static void substituteTPH(List<TPHConstraint> allCons, String oldName, String newName) {
allCons.forEach(c->{
if(c.getLeft().equals(oldName))
c.setLeft(newName);
if(c.getRight().equals(oldName))
c.setRight(newName);
});
}
public static void modifyRelation(List<SimpleCycle> simpleCycles) {
simpleCycles.forEach(sc->{
sc.getConstraint().setRel(Relation.EQUAL);
sc.getReverseConstraint().setRel(Relation.EQUAL);
});
}
public static void removeAllReverseConstraints(List<TPHConstraint> allCons, List<SimpleCycle> simpleCycles) {
simpleCycles.forEach(sc->allCons.remove(sc.getReverseConstraint()));
}
public static void substituteTPH(List<TPHConstraint> allCons, List<SimpleCycle> simpleCycles) {
simpleCycles.forEach(sc->substituteTPH(allCons, sc.getConstraint().getLeft(), sc.getConstraint().getRight()));
}
}

View File

@ -0,0 +1,38 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGenerator;
import java.util.List;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
/**
* @author fayez
*
*/
public class LongCycle {
private final List<TPHConstraint> constraints;
/**
* @param constraints
*/
public LongCycle(List<TPHConstraint> constraints) {
this.constraints = constraints;
}
/**
* @return the constraints
*/
public List<TPHConstraint> getConstraints() {
return constraints;
}
public boolean containConstraint(TPHConstraint constraint) {
for(TPHConstraint c : constraints) {
if(c.equalConstraint(constraint))
return true;
}
return false;
}
}

View File

@ -0,0 +1,69 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGenerator;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
/**
* @author fayez
*
*/
public class SimpleCycle {
private TPHConstraint constraint;
private TPHConstraint reverseConstraint;
/**
* @param constraint
* @param reverseConstraint
*/
public SimpleCycle(TPHConstraint constraint, TPHConstraint reverseConstraint) {
this.constraint = constraint;
this.reverseConstraint = reverseConstraint;
}
/**
* @return the constraint
*/
public TPHConstraint getConstraint() {
return constraint;
}
/**
* @param constraint the constraint to set
*/
public void setConstraint(TPHConstraint constraint) {
this.constraint = constraint;
}
/**
* @return the reverseConstraint
*/
public TPHConstraint getReverseConstraint() {
return reverseConstraint;
}
/**
* @param reverseConstraint the reverseConstraint to set
*/
public void setReverseConstraint(TPHConstraint reverseConstraint) {
this.reverseConstraint = reverseConstraint;
}
public boolean contains(TPHConstraint c) {
if (constraint.getLeft().equals(c.getLeft()) && constraint.getRight().equals(c.getRight())
&& constraint.getRel().equals(c.getRel()))
return true;
if (reverseConstraint.getLeft().equals(c.getLeft()) && reverseConstraint.getRight().equals(c.getRight())
&& reverseConstraint.getRel().equals(c.getRel()))
return true;
return false;
}
@Override
public String toString() {
return constraint.toString() + " -> " + reverseConstraint.toString();
}
}

View File

@ -318,7 +318,7 @@ public class Signature {
break;
case "TPH":
RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType;
// der Fall wenn die Type eine Interface ist, muss betrachtet werden
// der Fall wenn der Typ eine Interface ist, muss betrachtet werden
// Deswegen muss in ResutSet noch enthalten werden, ob die Type eine
// Interface oder eine Klasse ist.

View File

@ -0,0 +1,55 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.simplifyRes;
import java.util.Set;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
/**
* @author fayez
*
*/
public class GenericsGeneratorResult {
private TPHConstraint constraint;
/**
* contains the names of all type placeholders which are equals to the left side of
* the constraint {@link #constraint}.
*/
private Set<String> equalsTPHs;
/**
* @param constraint
* @param equalsTPHs
*/
public GenericsGeneratorResult(TPHConstraint constraint, Set<String> equalsTPHs) {
this.constraint = constraint;
this.equalsTPHs = equalsTPHs;
}
/**
* @return the constraint
*/
public TPHConstraint getConstraint() {
return constraint;
}
/**
* @param constraint the constraint to set
*/
public void setConstraint(TPHConstraint constraint) {
this.constraint = constraint;
}
/**
* @return the equalsTPHs
*/
public Set<String> getEqualsTPHs() {
return equalsTPHs;
}
/**
* @param equalsTPHs the equalsTPHs to set
*/
public void setEqualsTPHs(Set<String> equalsTPHs) {
this.equalsTPHs = equalsTPHs;
}
}

View File

@ -17,6 +17,7 @@ import de.dhbwstuttgart.bytecode.BytecodeGen;
import de.dhbwstuttgart.bytecode.TPHExtractor;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
import de.dhbwstuttgart.bytecode.genericsGenerator.GenericsGenerator;
import de.dhbwstuttgart.bytecode.signature.Signature;
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
import de.dhbwstuttgart.bytecode.signature.TypeToString;
@ -274,7 +275,7 @@ public class SimplifyResultFinder implements ASTVisitor {
// zwite operand muss weggelassen werden
if (hasGenInParameterList || resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString())
.equals("TPH")) {
List<GenericsGeneratorResult> ggR = GenericsGenerator.generateConstraintsForMethod(method, tphExtractor, tphsClass);
Map<TPHConstraint, Set<String>> constraints = Simplify.simplifyConstraints(method,
tphExtractor, tphsClass);

View File

@ -0,0 +1,38 @@
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 SimpleCycleTest {
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 generateGen() throws Exception {
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/SimpleCycle.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("SimpleCycle");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
}

View File

@ -0,0 +1,8 @@
public class SimpleCycle {
m(a,b){
a = b;
b = a;
}
}