forked from JavaTX/JavaCompilerCore
Generics generator step 1
This commit is contained in:
parent
4f39eccecb
commit
d77f2176f2
@ -44,6 +44,10 @@ public class TPHConstraint {
|
|||||||
return left.equals(tph)||right.equals(tph);
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if(rel == Relation.EXTENDS) {
|
if(rel == Relation.EXTENDS) {
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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()));
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -318,7 +318,7 @@ public class Signature {
|
|||||||
break;
|
break;
|
||||||
case "TPH":
|
case "TPH":
|
||||||
RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType;
|
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
|
// Deswegen muss in ResutSet noch enthalten werden, ob die Type eine
|
||||||
// Interface oder eine Klasse ist.
|
// Interface oder eine Klasse ist.
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -17,6 +17,7 @@ import de.dhbwstuttgart.bytecode.BytecodeGen;
|
|||||||
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
||||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||||
|
import de.dhbwstuttgart.bytecode.genericsGenerator.GenericsGenerator;
|
||||||
import de.dhbwstuttgart.bytecode.signature.Signature;
|
import de.dhbwstuttgart.bytecode.signature.Signature;
|
||||||
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
||||||
import de.dhbwstuttgart.bytecode.signature.TypeToString;
|
import de.dhbwstuttgart.bytecode.signature.TypeToString;
|
||||||
@ -274,7 +275,7 @@ public class SimplifyResultFinder implements ASTVisitor {
|
|||||||
// zwite operand muss weggelassen werden
|
// zwite operand muss weggelassen werden
|
||||||
if (hasGenInParameterList || resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString())
|
if (hasGenInParameterList || resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString())
|
||||||
.equals("TPH")) {
|
.equals("TPH")) {
|
||||||
|
List<GenericsGeneratorResult> ggR = GenericsGenerator.generateConstraintsForMethod(method, tphExtractor, tphsClass);
|
||||||
Map<TPHConstraint, Set<String>> constraints = Simplify.simplifyConstraints(method,
|
Map<TPHConstraint, Set<String>> constraints = Simplify.simplifyConstraints(method,
|
||||||
tphExtractor, tphsClass);
|
tphExtractor, tphsClass);
|
||||||
|
|
||||||
|
38
src/test/java/bytecode/SimpleCycleTest.java
Normal file
38
src/test/java/bytecode/SimpleCycleTest.java
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
8
src/test/resources/bytecode/javFiles/SimpleCycle.jav
Normal file
8
src/test/resources/bytecode/javFiles/SimpleCycle.jav
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
public class SimpleCycle {
|
||||||
|
|
||||||
|
m(a,b){
|
||||||
|
a = b;
|
||||||
|
b = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user