forked from JavaTX/JavaCompilerCore
Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into unify-test
This commit is contained in:
commit
4da4966b86
8
pom.xml
8
pom.xml
@ -38,11 +38,19 @@
|
|||||||
<artifactId>reflections</artifactId>
|
<artifactId>reflections</artifactId>
|
||||||
<version>0.9.11</version>
|
<version>0.9.11</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.ow2.asm</groupId>
|
||||||
|
<artifactId>asm</artifactId>
|
||||||
|
<version>7.0</version>
|
||||||
|
</dependency>
|
||||||
|
<!--
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.ow2.asm</groupId>
|
<groupId>org.ow2.asm</groupId>
|
||||||
<artifactId>asm-all</artifactId>
|
<artifactId>asm-all</artifactId>
|
||||||
<version>[4.0.0,)</version>
|
<version>[4.0.0,)</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
-->
|
||||||
<!--
|
<!--
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.bitbucket.mstrobel</groupId>
|
<groupId>org.bitbucket.mstrobel</groupId>
|
||||||
|
@ -125,6 +125,7 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
for(ResultSet rs : listOfResultSets) {
|
for(ResultSet rs : listOfResultSets) {
|
||||||
superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor());
|
superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor());
|
||||||
resultSet = rs;
|
resultSet = rs;
|
||||||
|
tphExtractor.setResultSet(resultSet);
|
||||||
// Nur einmal ausführen!!
|
// Nur einmal ausführen!!
|
||||||
if(!isVisited) {
|
if(!isVisited) {
|
||||||
classOrInterface.accept(tphExtractor);
|
classOrInterface.accept(tphExtractor);
|
||||||
@ -558,52 +559,5 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TPHExtractor extends AbstractASTWalker{
|
|
||||||
// Alle TPHs der Felder werden iKopf der Klasse definiert
|
|
||||||
// alle TPHs der Klasse: (TPH, is in Method?)
|
|
||||||
final HashMap<TypePlaceholder,Boolean> allTPHS = new HashMap<>();
|
|
||||||
MethodAndTPH methodAndTph;
|
|
||||||
Boolean inMethod = false;
|
|
||||||
public final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
|
|
||||||
final ArrayList<GenericInsertPair> allPairs = new ArrayList<>();
|
|
||||||
public final ArrayList<TPHConstraint> allCons = new ArrayList<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(TypePlaceholder tph) {
|
|
||||||
if(resultSet.resolveType(tph).resolvedType instanceof TypePlaceholder) {
|
|
||||||
TypePlaceholder resolvedTPH = (TypePlaceholder) resultSet.resolveType(tph).resolvedType;
|
|
||||||
if(inMethod)
|
|
||||||
methodAndTph.getTphs().add(resolvedTPH);
|
|
||||||
|
|
||||||
allTPHS.put(resolvedTPH,inMethod);
|
|
||||||
resultSet.resolveType(tph).additionalGenerics.forEach(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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) {
|
|
||||||
for(int i=0; i<pairs.size();++i) {
|
|
||||||
GenericInsertPair p = pairs.get(i);
|
|
||||||
if(p.TA1.equals(genPair.TA1) && p.TA2.equals(genPair.TA2))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void visit(Method method) {
|
|
||||||
inMethod = true;
|
|
||||||
methodAndTph = new MethodAndTPH(method.name);
|
|
||||||
super.visit(method);
|
|
||||||
inMethod = false;
|
|
||||||
ListOfMethodsAndTph.add(methodAndTph);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -805,10 +805,12 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
if(methodRefl != null && !methodRefl.getReturnType().isPrimitive()) {
|
if(methodRefl != null && !methodRefl.getReturnType().isPrimitive()) {
|
||||||
if(methodRefl.getReturnType().equals(Object.class)) {
|
if(methodRefl.getReturnType().equals(Object.class)) {
|
||||||
String checkCast = getResolvedType(methodCall.getType());
|
String checkCast = getResolvedType(methodCall.getType());
|
||||||
int pos = checkCast.length();
|
if(!checkCast.contains("TPH ")) {
|
||||||
if(checkCast.contains("<"))
|
int pos = checkCast.length();
|
||||||
pos = checkCast.indexOf("<");
|
if(checkCast.contains("<"))
|
||||||
mv.visitTypeInsn(Opcodes.CHECKCAST,checkCast.substring(0,pos));
|
pos = checkCast.indexOf("<");
|
||||||
|
mv.visitTypeInsn(Opcodes.CHECKCAST,checkCast.substring(0,pos));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(isBinaryExp)
|
if(isBinaryExp)
|
||||||
doUnboxing(getResolvedType(methodCall.getType()));
|
doUnboxing(getResolvedType(methodCall.getType()));
|
||||||
|
78
src/de/dhbwstuttgart/bytecode/TPHExtractor.java
Normal file
78
src/de/dhbwstuttgart/bytecode/TPHExtractor.java
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
|
import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
|
||||||
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fayez Abu Alia
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TPHExtractor extends AbstractASTWalker{
|
||||||
|
// Alle TPHs der Felder werden iKopf der Klasse definiert
|
||||||
|
// alle TPHs der Klasse: (TPH, is in Method?)
|
||||||
|
final HashMap<TypePlaceholder,Boolean> allTPHS = new HashMap<>();
|
||||||
|
MethodAndTPH methodAndTph;
|
||||||
|
Boolean inMethod = false;
|
||||||
|
public final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
|
||||||
|
final ArrayList<GenericInsertPair> allPairs = new ArrayList<>();
|
||||||
|
public final ArrayList<TPHConstraint> allCons = new ArrayList<>();
|
||||||
|
private ResultSet resultSet;
|
||||||
|
|
||||||
|
public TPHExtractor() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultSet(ResultSet resultSet) {
|
||||||
|
this.resultSet = resultSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(TypePlaceholder tph) {
|
||||||
|
if(resultSet.resolveType(tph).resolvedType instanceof TypePlaceholder) {
|
||||||
|
TypePlaceholder resolvedTPH = (TypePlaceholder) resultSet.resolveType(tph).resolvedType;
|
||||||
|
if(inMethod)
|
||||||
|
methodAndTph.getTphs().add(resolvedTPH.getName());
|
||||||
|
|
||||||
|
allTPHS.put(resolvedTPH,inMethod);
|
||||||
|
resultSet.resolveType(tph).additionalGenerics.forEach(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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) {
|
||||||
|
for(int i=0; i<pairs.size();++i) {
|
||||||
|
GenericInsertPair p = pairs.get(i);
|
||||||
|
if(p.TA1.equals(genPair.TA1) && p.TA2.equals(genPair.TA2))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void visit(Method method) {
|
||||||
|
inMethod = true;
|
||||||
|
methodAndTph = new MethodAndTPH(method.name);
|
||||||
|
super.visit(method);
|
||||||
|
inMethod = false;
|
||||||
|
ListOfMethodsAndTph.add(methodAndTph);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -8,14 +8,14 @@ import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
|
|||||||
public class MethodAndTPH {
|
public class MethodAndTPH {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private final ArrayList<TypePlaceholder> tphs = new ArrayList<>();
|
private final ArrayList<String> tphs = new ArrayList<>();
|
||||||
private final ArrayList<GenericInsertPair> pairs = new ArrayList<>();
|
private final ArrayList<GenericInsertPair> pairs = new ArrayList<>();
|
||||||
|
|
||||||
public MethodAndTPH(String name) {
|
public MethodAndTPH(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<TypePlaceholder> getTphs() {
|
public ArrayList<String> getTphs() {
|
||||||
return tphs;
|
return tphs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import java.util.LinkedList;
|
|||||||
|
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.BytecodeGen.TPHExtractor;
|
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
||||||
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
@ -16,7 +16,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) {
|
||||||
// 1. check if there are any 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
|
||||||
// * substitute L with R in all constraint
|
// * substitute L with R in all constraint
|
||||||
@ -28,8 +28,10 @@ public class Simplify {
|
|||||||
// b) no
|
// b) no
|
||||||
// 3. is
|
// 3. is
|
||||||
|
|
||||||
|
// 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<>();
|
||||||
|
|
||||||
// step 1:
|
// step 1:
|
||||||
for(TPHConstraint c : allCons) {
|
for(TPHConstraint c : allCons) {
|
||||||
|
|
||||||
@ -39,12 +41,16 @@ public class Simplify {
|
|||||||
TPHConstraint revCon = getReverseConstraint(allCons,left,right);
|
TPHConstraint revCon = getReverseConstraint(allCons,left,right);
|
||||||
if(revCon != null) {
|
if(revCon != null) {
|
||||||
revCon.setRel(Relation.EQUAL);
|
revCon.setRel(Relation.EQUAL);
|
||||||
|
// the reverse constraint is removed because
|
||||||
|
// otherwise there is twice the same constraint
|
||||||
|
// (e.g. A<B and B<A => A=B and B=A)
|
||||||
consToRemove.add(revCon);
|
consToRemove.add(revCon);
|
||||||
c.setRel(Relation.EQUAL);
|
c.setRel(Relation.EQUAL);
|
||||||
substituteTPH(allCons,left, right);
|
substituteTPH(allCons,left, right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println();
|
System.out.println();
|
||||||
System.out.println("NEW ALL CONST: " + allCons.size());
|
System.out.println("NEW ALL CONST: " + allCons.size());
|
||||||
allCons.forEach(c->System.out.println(c.toString()));
|
allCons.forEach(c->System.out.println(c.toString()));
|
||||||
@ -59,17 +65,100 @@ public class Simplify {
|
|||||||
System.out.println("----------------");
|
System.out.println("----------------");
|
||||||
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||||
|
|
||||||
|
// check if there is any long cycle (e.g. A<B<C<A)
|
||||||
|
|
||||||
|
// to save all types that are in relation
|
||||||
|
LinkedList<String> allTypes = new LinkedList<>();
|
||||||
|
// we will put all constraints which are in the cycle, in this ArrayList.
|
||||||
|
// Later these contraints will be converted to equal-constraints
|
||||||
|
ArrayList<TPHConstraint> constraints = new ArrayList<>(size);
|
||||||
|
int visited = 0;
|
||||||
|
|
||||||
|
// contains all constraints
|
||||||
|
HashMap<String,String> ss1 = new HashMap<>();
|
||||||
|
|
||||||
|
for(TPHConstraint constr : allCons) {
|
||||||
|
ss1.put(constr.getLeft(), constr.getRight());
|
||||||
|
}
|
||||||
|
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
|
||||||
|
if(visited >= size)
|
||||||
|
break;
|
||||||
|
// Only extends-constraints will be checked
|
||||||
|
if(c.getRel() == Relation.EXTENDS) {
|
||||||
|
++visited;
|
||||||
|
|
||||||
|
String left = c.getLeft();
|
||||||
|
String right = c.getRight();
|
||||||
|
// put the types in linked list
|
||||||
|
allTypes.add(left);
|
||||||
|
allTypes.add(right);
|
||||||
|
|
||||||
|
constraints.add(c);
|
||||||
|
|
||||||
|
boolean isCycle = false;
|
||||||
|
|
||||||
|
// iterate through the map to check if there is a cycle
|
||||||
|
while(ss1.containsKey(right)) {
|
||||||
|
++visited;
|
||||||
|
String oldRight = right;
|
||||||
|
right = ss1.get(right);
|
||||||
|
|
||||||
|
TPHConstraint toAdd = getConstraint(oldRight, right, allCons);
|
||||||
|
|
||||||
|
if(toAdd != null)
|
||||||
|
constraints.add(toAdd);
|
||||||
|
|
||||||
|
if(left.equals(right)) {
|
||||||
|
isCycle = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
allTypes.add(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isCycle) {
|
||||||
|
// convert all constraints to equal constraints
|
||||||
|
setAllEqual(constraints);
|
||||||
|
// these constraints will be removed from allCons
|
||||||
|
consToRemove.addAll(constraints);
|
||||||
|
// all equal types will be substitute with one type
|
||||||
|
substituteAllTPH(allCons,constraints,left);
|
||||||
|
|
||||||
|
HashSet<String> eq = new HashSet<>();
|
||||||
|
// put all equal types in a set
|
||||||
|
for(String t:allTypes) {
|
||||||
|
eq.add(t);
|
||||||
|
}
|
||||||
|
// generate a new constraint (left < Object)
|
||||||
|
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();
|
||||||
|
allTypes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 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) {
|
for(TPHConstraint c : allCons) {
|
||||||
if(c.getRel()==Relation.EQUAL) {
|
if(c.getRel()==Relation.EQUAL) {
|
||||||
HashSet<String> equalTPHs = getEqualsTPHs(result, c);
|
if(!isTPHInResEqual(result, c.getLeft())) {
|
||||||
TPHConstraint constraint = getKeyConstraint(result,c);
|
HashSet<String> equalTPHs = getEqualsTPHs(result, c);
|
||||||
equalTPHs.add(c.getLeft());
|
TPHConstraint constraint = getKeyConstraint(result,c);
|
||||||
equalTPHs.add(c.getRight());
|
equalTPHs.add(c.getLeft());
|
||||||
result.put(constraint, equalTPHs);
|
equalTPHs.add(c.getRight());
|
||||||
|
result.put(constraint, equalTPHs);
|
||||||
|
}
|
||||||
consToRemove.add(c);
|
consToRemove.add(c);
|
||||||
size--;
|
size--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Step 2 Result: ");
|
System.out.println("Step 2 Result: ");
|
||||||
result.forEach((c,hs)->{
|
result.forEach((c,hs)->{
|
||||||
System.out.print(c.toString() + " -> ");
|
System.out.print(c.toString() + " -> ");
|
||||||
@ -79,7 +168,9 @@ public class Simplify {
|
|||||||
System.out.println();
|
System.out.println();
|
||||||
});
|
});
|
||||||
System.out.println("----------------");
|
System.out.println("----------------");
|
||||||
|
// remove all equal-constraints
|
||||||
allCons.removeAll(consToRemove);
|
allCons.removeAll(consToRemove);
|
||||||
|
// add all generated constraints to allCons
|
||||||
allCons.addAll(result.keySet());
|
allCons.addAll(result.keySet());
|
||||||
|
|
||||||
if(!allCons.isEmpty() && allCons.size()<2) {
|
if(!allCons.isEmpty() && allCons.size()<2) {
|
||||||
@ -91,19 +182,23 @@ public class Simplify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size += result.keySet().size();
|
size += result.keySet().size();
|
||||||
|
// all constraints which have Object on the right side will
|
||||||
|
// be ignored, because they are simplified and can not be changed.
|
||||||
for(TPHConstraint c : allCons) {
|
for(TPHConstraint c : allCons) {
|
||||||
if(c.getRight().equals(Type.getInternalName(Object.class)))
|
if(c.getRight().equals(Type.getInternalName(Object.class)))
|
||||||
size--;
|
size--;
|
||||||
}
|
}
|
||||||
ArrayList<TypePlaceholder> methodTphs = new ArrayList<>();
|
// get all tph of the method
|
||||||
|
ArrayList<String> methodTphs = new ArrayList<>();
|
||||||
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
|
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
|
||||||
if(m.getName().equals(name)) {
|
if(m.getName().equals(name)) {
|
||||||
methodTphs = m.getTphs();
|
methodTphs = m.getTphs();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// check if there are multiple constraint with the same left side.
|
||||||
|
// if yes => check if the super type in the method, if not
|
||||||
|
// then ignore it.
|
||||||
HashMap<String, String> subAndSuper = new HashMap<>();
|
HashMap<String, String> subAndSuper = new HashMap<>();
|
||||||
for(TPHConstraint c : allCons) {
|
for(TPHConstraint c : allCons) {
|
||||||
if(subAndSuper.containsKey(c.getLeft())) {
|
if(subAndSuper.containsKey(c.getLeft())) {
|
||||||
@ -155,6 +250,8 @@ public class Simplify {
|
|||||||
// Die größte Supertype
|
// Die größte Supertype
|
||||||
String superTphRes = tphInRel.getLast();
|
String superTphRes = tphInRel.getLast();
|
||||||
|
|
||||||
|
// if there is any constraint X < subTph, then
|
||||||
|
// 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(containTPH(methodTphs,tph) && subAndSuper.get(tph).equals(subTphRes)) {
|
if(containTPH(methodTphs,tph) && subAndSuper.get(tph).equals(subTphRes)) {
|
||||||
@ -165,12 +262,18 @@ public class Simplify {
|
|||||||
if(subTphRes.equals(tphInRel.getFirst())) {
|
if(subTphRes.equals(tphInRel.getFirst())) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isTPHInConstraint(result, subTphRes))
|
||||||
|
break;
|
||||||
|
|
||||||
tphInRel.addFirst(subTphRes);
|
tphInRel.addFirst(subTphRes);
|
||||||
numOfVisitedPairs++;
|
numOfVisitedPairs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
subTphRes = tphInRel.getFirst();
|
subTphRes = tphInRel.getFirst();
|
||||||
|
// if the last type in the list not a type in method-types
|
||||||
|
// then find the last type in front of this type, which is
|
||||||
|
// a type in method-types
|
||||||
int i = 2;
|
int i = 2;
|
||||||
while(!containTPH(methodTphs,superTphRes) && (tphInRel.size()-i) >0) {
|
while(!containTPH(methodTphs,superTphRes) && (tphInRel.size()-i) >0) {
|
||||||
superTphRes = tphInRel.get(tphInRel.size()-i);
|
superTphRes = tphInRel.get(tphInRel.size()-i);
|
||||||
@ -181,13 +284,14 @@ public class Simplify {
|
|||||||
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 {
|
} else {
|
||||||
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), null);
|
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), null);
|
||||||
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
if(!isTPHInConstraint(result, superTphRes))
|
||||||
|
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(TypePlaceholder tph : methodTphs) {
|
for(String tph : methodTphs) {
|
||||||
if(!isTPHInConstraint(result, tph.getName())) {
|
if(!isTPHInConstraint(result, tph)) {
|
||||||
result.put(new ExtendsConstraint(tph.getName(), Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
result.put(new ExtendsConstraint(tph, Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,6 +315,44 @@ public class Simplify {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static TPHConstraint getConstraint(String oldRight, String right, ArrayList<TPHConstraint> allCons) {
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
if(c.getLeft().equals(oldRight) && c.getRight().equals(right))
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isTPHInResEqual(HashMap<TPHConstraint, HashSet<String>> result, String left) {
|
||||||
|
for(HashSet<String> eq : result.values()) {
|
||||||
|
if(eq.contains(left)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void substituteAllTPH(ArrayList<TPHConstraint> allCons, ArrayList<TPHConstraint> constraints,
|
||||||
|
String first) {
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
for(TPHConstraint c2 : constraints) {
|
||||||
|
if(c.getRel() == Relation.EXTENDS) {
|
||||||
|
if(c2.getLeft().equals(c.getLeft()) || c2.getRight().equals(c.getLeft()))
|
||||||
|
c.setLeft(first);
|
||||||
|
if(c2.getLeft().equals(c.getRight()) || c2.getRight().equals(c.getRight()))
|
||||||
|
c.setRight(first);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setAllEqual(ArrayList<TPHConstraint> constraints) {
|
||||||
|
for(TPHConstraint c:constraints) {
|
||||||
|
c.setRel(Relation.EQUAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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:
|
// 1. check if there are any cycles like L<R and R<L:
|
||||||
// a) yes => set L=R and:
|
// a) yes => set L=R and:
|
||||||
@ -406,9 +548,9 @@ public class Simplify {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean containTPH(ArrayList<TypePlaceholder> methodTphs, String sub) {
|
private static boolean containTPH(ArrayList<String> methodTphs, String sub) {
|
||||||
for(TypePlaceholder tph : methodTphs) {
|
for(String tph : methodTphs) {
|
||||||
if(tph.getName().equals(sub))
|
if(tph.equals(sub))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
Binary file not shown.
4
target/repository/.gitignore
vendored
4
target/repository/.gitignore
vendored
@ -1,4 +0,0 @@
|
|||||||
# Ignore everything in this directory
|
|
||||||
*
|
|
||||||
# Except this file
|
|
||||||
!.gitignore
|
|
@ -32,22 +32,24 @@ public class FacultyTest {
|
|||||||
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
classToTest = loader.loadClass("Faculty");
|
classToTest = loader.loadClass("Faculty");
|
||||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
// Method m = classToTest.getDeclaredMethod("m", Integer.class);
|
Method getFact = classToTest.getDeclaredMethod("getFact", Integer.class);
|
||||||
Field fact = classToTest.getDeclaredField("fact");
|
// Field fact = classToTest.getDeclaredField("fact");
|
||||||
// Class<?> lambda = m.invoke(instanceOfClass).getClass();
|
// Class<?> lambda = m.invoke(instanceOfClass).getClass();
|
||||||
Class<?> lambda = fact.getType();
|
// Class<?> lambda = fact.getType();
|
||||||
Method apply = lambda.getMethod("apply", Object.class);
|
// System.out.println(fact.getType().getName());
|
||||||
//
|
// Method apply = lambda.getMethod("apply", Object.class);
|
||||||
|
// System.out.println(lambda.getMethods()[0]);
|
||||||
|
// System.out.println(instanceOfClass.toString());
|
||||||
// // Damit man auf die Methode zugreifen kann
|
// // Damit man auf die Methode zugreifen kann
|
||||||
apply.setAccessible(true);
|
// apply.setAccessible(true);
|
||||||
// Field value
|
// Field value
|
||||||
Object fieldVal = fact.get(instanceOfClass);
|
// Object fieldVal = fact.get(instanceOfClass);
|
||||||
Integer i = 3;
|
Integer i = 3;
|
||||||
Method applyFromField = fieldVal.getClass().getDeclaredMethod("apply", Object.class);
|
// Method applyFromField = fieldVal.getClass().getDeclaredMethod("apply", Object.class);
|
||||||
applyFromField.setAccessible(true);
|
// applyFromField.setAccessible(true);
|
||||||
Integer result = (Integer) applyFromField.invoke(instanceOfClass, i);
|
// Integer result = (Integer) apply.invoke(lambda,i);
|
||||||
// Integer result = (Integer) m.invoke(instanceOfClass,i);
|
Integer result = (Integer) getFact.invoke(instanceOfClass,i);
|
||||||
|
|
||||||
assertEquals(6, result);
|
assertEquals(6, result);
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ public class LambdaTest {
|
|||||||
apply.setAccessible(true);
|
apply.setAccessible(true);
|
||||||
|
|
||||||
Integer i = 77;
|
Integer i = 77;
|
||||||
|
System.out.println(m.invoke(instanceOfClass).toString());
|
||||||
Integer result = (Integer) apply.invoke(m.invoke(instanceOfClass), i);
|
Integer result = (Integer) apply.invoke(m.invoke(instanceOfClass), i);
|
||||||
|
|
||||||
assertEquals(77, result);
|
assertEquals(77, result);
|
||||||
|
@ -13,6 +13,10 @@ public class Faculty {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public getFact(x) {
|
||||||
|
return fact.apply(x);
|
||||||
|
}
|
||||||
// m (x) {
|
// m (x) {
|
||||||
//
|
//
|
||||||
//// var fact = (x) -> {
|
//// var fact = (x) -> {
|
||||||
|
@ -2,8 +2,8 @@ public class Tph {
|
|||||||
|
|
||||||
m(a,b){
|
m(a,b){
|
||||||
var c = m2(b);
|
var c = m2(b);
|
||||||
return a;
|
// return a;
|
||||||
// return m2(b);
|
return m2(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
m2(b){
|
m2(b){
|
||||||
|
76
test/bytecode/simplifyalgo/CycleTest.java
Normal file
76
test/bytecode/simplifyalgo/CycleTest.java
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package bytecode.simplifyalgo;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.Simplify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fayez Abu Alia
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CycleTest {
|
||||||
|
|
||||||
|
private static TPHExtractor tphExtractor;
|
||||||
|
private static String methName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws java.lang.Exception
|
||||||
|
*/
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
tphExtractor = new TPHExtractor();
|
||||||
|
// A < B
|
||||||
|
TPHConstraint c1 = new ExtendsConstraint("A", "B", Relation.EXTENDS);
|
||||||
|
// B < C
|
||||||
|
TPHConstraint c2 = new ExtendsConstraint("B", "C", Relation.EXTENDS);
|
||||||
|
// C < D
|
||||||
|
TPHConstraint c3 = new ExtendsConstraint("C", "D", Relation.EXTENDS);
|
||||||
|
// D < A
|
||||||
|
TPHConstraint c4 = new ExtendsConstraint("D", "A", Relation.EXTENDS);
|
||||||
|
// name
|
||||||
|
methName = "m";
|
||||||
|
MethodAndTPH mtph = new MethodAndTPH("m");
|
||||||
|
mtph.getTphs().add("A");
|
||||||
|
mtph.getTphs().add("B");
|
||||||
|
mtph.getTphs().add("C");
|
||||||
|
mtph.getTphs().add("D");
|
||||||
|
tphExtractor.ListOfMethodsAndTph.add(mtph);
|
||||||
|
tphExtractor.allCons.add(c1);
|
||||||
|
tphExtractor.allCons.add(c2);
|
||||||
|
tphExtractor.allCons.add(c3);
|
||||||
|
tphExtractor.allCons.add(c4);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||||
|
HashSet<String> equals = new HashSet<>();
|
||||||
|
equals.add("A");
|
||||||
|
equals.add("B");
|
||||||
|
equals.add("C");
|
||||||
|
equals.add("D");
|
||||||
|
TPHConstraint k = new ExtendsConstraint("A", Type.getInternalName(Object.class), Relation.EXTENDS);
|
||||||
|
result.put(k, equals);
|
||||||
|
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor);
|
||||||
|
boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
|
||||||
|
assertTrue(areEquals);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
97
test/bytecode/simplifyalgo/SameLeftSide.java
Normal file
97
test/bytecode/simplifyalgo/SameLeftSide.java
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
package bytecode.simplifyalgo;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.Simplify;
|
||||||
|
import de.dhbwstuttgart.typedeployment.TypeInsertPlacer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Fayez Abu Alia
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SameLeftSide {
|
||||||
|
// Typeplaceholders können nicht definiert werden, da die Konstruktor
|
||||||
|
// private ist => Test geht nicht
|
||||||
|
private static TPHExtractor tphExtractor;
|
||||||
|
private static String methName;
|
||||||
|
private static String methName2;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
tphExtractor = new TPHExtractor();
|
||||||
|
// A < B
|
||||||
|
TPHConstraint c1 = new ExtendsConstraint("A", "B", Relation.EXTENDS);
|
||||||
|
// A < C
|
||||||
|
TPHConstraint c2 = new ExtendsConstraint("A", "C", Relation.EXTENDS);
|
||||||
|
// B < D
|
||||||
|
TPHConstraint c3 = new ExtendsConstraint("B", "D", Relation.EXTENDS);
|
||||||
|
// C < E
|
||||||
|
TPHConstraint c4 = new ExtendsConstraint("C", "E", Relation.EXTENDS);
|
||||||
|
// name
|
||||||
|
methName = "m1";
|
||||||
|
MethodAndTPH m1 = new MethodAndTPH("m1");
|
||||||
|
|
||||||
|
methName2 = "m2";
|
||||||
|
MethodAndTPH m2 = new MethodAndTPH("m2");
|
||||||
|
|
||||||
|
m1.getTphs().add("A");
|
||||||
|
m1.getTphs().add("B");
|
||||||
|
m1.getTphs().add("D");
|
||||||
|
|
||||||
|
m2.getTphs().add("C");
|
||||||
|
m2.getTphs().add("E");
|
||||||
|
|
||||||
|
tphExtractor.ListOfMethodsAndTph.add(m1);
|
||||||
|
tphExtractor.ListOfMethodsAndTph.add(m2);
|
||||||
|
|
||||||
|
tphExtractor.allCons.add(c1);
|
||||||
|
tphExtractor.allCons.add(c2);
|
||||||
|
tphExtractor.allCons.add(c3);
|
||||||
|
tphExtractor.allCons.add(c4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testM1() {
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||||
|
|
||||||
|
TPHConstraint d = new ExtendsConstraint("D", Type.getInternalName(Object.class), Relation.EXTENDS);
|
||||||
|
TPHConstraint a = new ExtendsConstraint("A", "D", Relation.EXTENDS);
|
||||||
|
TPHConstraint b = new ExtendsConstraint("B", "D", Relation.EXTENDS);
|
||||||
|
result.put(d, null);
|
||||||
|
result.put(a, null);
|
||||||
|
result.put(b, null);
|
||||||
|
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor);
|
||||||
|
boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
|
||||||
|
assertTrue(areEquals);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testM2() {
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||||
|
|
||||||
|
TPHConstraint e = new ExtendsConstraint("E", Type.getInternalName(Object.class), Relation.EXTENDS);
|
||||||
|
TPHConstraint c = new ExtendsConstraint("C", "E", Relation.EXTENDS);
|
||||||
|
|
||||||
|
result.put(e, null);
|
||||||
|
result.put(c, null);
|
||||||
|
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName2, tphExtractor);
|
||||||
|
boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
|
||||||
|
assertTrue(areEquals);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
79
test/bytecode/simplifyalgo/SimpleCycle.java
Normal file
79
test/bytecode/simplifyalgo/SimpleCycle.java
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package bytecode.simplifyalgo;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.Simplify;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Fayez Abu Alia
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SimpleCycle {
|
||||||
|
private static TPHExtractor tphExtractor;
|
||||||
|
private static String methName;
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
tphExtractor = new TPHExtractor();
|
||||||
|
// A < B
|
||||||
|
TPHConstraint c1 = new ExtendsConstraint("A", "B", Relation.EXTENDS);
|
||||||
|
// B < A
|
||||||
|
TPHConstraint c2 = new ExtendsConstraint("B", "A", Relation.EXTENDS);
|
||||||
|
// name
|
||||||
|
methName = "m";
|
||||||
|
tphExtractor.allCons.add(c1);
|
||||||
|
tphExtractor.allCons.add(c2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||||
|
HashSet<String> equals = new HashSet<>();
|
||||||
|
equals.add("A");
|
||||||
|
equals.add("B");
|
||||||
|
TPHConstraint k = new ExtendsConstraint("B", Type.getInternalName(Object.class), Relation.EXTENDS);
|
||||||
|
result.put(k, equals);
|
||||||
|
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor);
|
||||||
|
boolean areEquals = areMapsEqual(result, sim);
|
||||||
|
assertTrue(areEquals);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean areMapsEqual(HashMap<TPHConstraint, HashSet<String>> m1, HashMap<TPHConstraint, HashSet<String>> m2) {
|
||||||
|
|
||||||
|
for(TPHConstraint c : m1.keySet()) {
|
||||||
|
for(TPHConstraint c2 : m2.keySet()) {
|
||||||
|
if(c.getLeft().equals(c2.getLeft()) && c.getRight().equals(c2.getRight()) && c.getRel()==c2.getRel()) {
|
||||||
|
HashSet<String> eq1 = m1.get(c);
|
||||||
|
HashSet<String> eq2 = m2.get(c2);
|
||||||
|
|
||||||
|
if((eq1 == null && eq2 != null) || (eq1 != null && eq2 == null))
|
||||||
|
return false;
|
||||||
|
if(eq1 != null) {
|
||||||
|
if(eq1.size() != eq2.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for(String tph:eq1) {
|
||||||
|
if(!eq2.contains(tph))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user