From d4d668b662804c83150b6ea6a1acb7574872141b Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 16 Jan 2019 14:41:33 +0100 Subject: [PATCH 01/19] Simplify fuer Klassen Type Variablen --- .../dhbwstuttgart/bytecode/BytecodeGen.java | 35 +-- .../dhbwstuttgart/bytecode/TPHExtractor.java | 8 + .../bytecode/utilities/Simplify.java | 239 ++++++++++++++++++ .../syntaxtree/AbstractASTWalker.java | 3 + src/test/java/bytecode/FieldTph.java | 43 ---- .../java/bytecode/FieldTphConsMethTest.java | 3 +- src/test/java/bytecode/MatrixOpTest.java | 22 +- .../resources/bytecode/javFiles/MatrixOP.jav | 2 +- 8 files changed, 288 insertions(+), 67 deletions(-) delete mode 100644 src/test/java/bytecode/FieldTph.java diff --git a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java index 0dea801d..fec01c10 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -147,23 +147,7 @@ public class BytecodeGen implements ASTVisitor { if(!tphExtractor.allTPHS.get(t)) tphsClass.add(t); } - - ArrayList consClass = new ArrayList<>(); - for(TPHConstraint cons : tphExtractor.allCons) { - TypePlaceholder right = null; - for(TypePlaceholder tph : tphsClass) { - if(cons.getLeft().equals(tph.getName())) { - - consClass.add(cons); - right = getTPH(cons.getRight()); - } - } - if(right != null) { - tphsClass.add(right); - removeFromMethod(right.getName()); - right = null; - } - } + String sig = null; /* if class has generics then creates signature * Signature looks like: @@ -172,6 +156,23 @@ public class BytecodeGen implements ASTVisitor { if(classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty() || classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<") || !tphsClass.isEmpty()) { + HashMap> constraints = Simplify.simplifyConstraintsClass(tphExtractor,tphsClass); + ArrayList consClass = new ArrayList<>(); + for(TPHConstraint cons : constraints.keySet()) { + TypePlaceholder right = null; + for(TypePlaceholder tph : tphsClass) { + if(cons.getLeft().equals(tph.getName())) { + + consClass.add(cons); + right = getTPH(cons.getRight()); + } + } + if(right != null) { + tphsClass.add(right); + removeFromMethod(right.getName()); + right = null; + } + } Signature signature = new Signature(classOrInterface, genericsAndBounds,commonPairs,tphsClass, consClass); sig = signature.toString(); System.out.println("Signature: => " + sig); diff --git a/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java b/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java index d9a95311..0135631e 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java @@ -11,6 +11,7 @@ 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.Constructor; import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.result.GenericInsertPair; @@ -75,4 +76,11 @@ public class TPHExtractor extends AbstractASTWalker{ ListOfMethodsAndTph.add(methodAndTph); } + @Override + public void visit(Constructor cons) { + inMethod = false; + super.visit(cons); + inMethod = true; + } + } \ No newline at end of file diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java index d19d38dc..2e3ce775 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java @@ -347,6 +347,245 @@ public class Simplify { return result; } + + public static HashMap> simplifyConstraintsClass(TPHExtractor tphExtractor, ArrayList tphsClass) { + // all constraints that will be simplified + ArrayList allCons = tphExtractor.allCons; + ArrayList consToRemove = new ArrayList<>(); + + // step 1: + for(TPHConstraint c : allCons) { + + String left = c.getLeft(); + String right = c.getRight(); + if(c.getRel() == Relation.EXTENDS) { + TPHConstraint revCon = getReverseConstraint(allCons,left,right); + if(revCon != null) { + revCon.setRel(Relation.EQUAL); + // the reverse constraint is removed because + // otherwise there is the same constraint twice + // (e.g. A A=B and B=A) + consToRemove.add(revCon); + c.setRel(Relation.EQUAL); + substituteTPH(allCons,left, right); + } + } + } + + + allCons.removeAll(consToRemove); + consToRemove = new ArrayList<>(); + + int size = allCons.size(); + + HashMap> result = new HashMap<>(); + + // check if there is any long cycle (e.g. A 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 constraints = new ArrayList<>(size); + int visited = 0; + + // contains all constraints + HashMap 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 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) { + if(c.getRel()==Relation.EQUAL) { + if(!isTPHInResEqual(result, c.getLeft())) { + HashSet 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()); + + if(!allCons.isEmpty() && allCons.size()<2) { + 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); + } + + return result; + } + + 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) { + if(c.getRight().equals(Type.getInternalName(Object.class))) + size--; + } + + // 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 subAndSuper = new HashMap<>(); + ArrayList eqCons = new ArrayList<>(); + for(TPHConstraint c : allCons) { + + subAndSuper.put(c.getLeft(), c.getRight()); + } + + int numOfVisitedPairs = 0; + for(String sub : subAndSuper.keySet()) { + if(isTPHInConstraint(result,sub)) + continue; + + if(!classTPHSContainsTPH(tphsClass,sub)) + continue; + + if(numOfVisitedPairs>=size) + break; + LinkedList tphInRel = new LinkedList<>(); + tphInRel.add(sub); + String superT = subAndSuper.get(sub); + tphInRel.add(superT); + + numOfVisitedPairs++; + while(subAndSuper.containsKey(superT)) { + superT = subAndSuper.get(superT); + if(tphInRel.contains(superT)) { + break; + } + tphInRel.add(superT); + numOfVisitedPairs++; + } + + // Subtype + String subTphRes = tphInRel.getFirst(); + // Die größte Supertype + String superTphRes = tphInRel.getLast(); + + // if there is any constraint X < subTph, then + // add X at the beginning of the list. + while(subAndSuper.containsValue(subTphRes)) { + for(String tph : subAndSuper.keySet()) { + if(classTPHSContainsTPH(tphsClass,tph) && subAndSuper.get(tph).equals(subTphRes)) { + subTphRes = tph; + break; + } + } + if(subTphRes.equals(tphInRel.getFirst())) { + break; + } + + if(isTPHInConstraint(result, subTphRes)) + break; + + tphInRel.addFirst(subTphRes); + numOfVisitedPairs++; + } + + subTphRes = tphInRel.getFirst(); + + + + HashSet equals = getEqualsTphsFromEqualCons(eqCons,superTphRes); + result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals); + + } + + System.out.println("EndResult: "); + result.forEach((c,hs)->{ + if(c!=null) { + System.out.print(c.toString() + " -> "); + if(hs == null) { + System.out.print(" [] "); + }else { + hs.forEach(s->{ + System.out.print(s + ", "); + }); + } + } + + + System.out.println(); + }); + System.out.println("----------------"); + return result; + } + + private static boolean classTPHSContainsTPH(ArrayList tphsClass, String superTphRes) { for(TypePlaceholder tph : tphsClass) { if(tph.getName().equals(superTphRes)) diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java b/src/main/java/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java index bf9fe263..6fd83f3b 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java @@ -80,6 +80,9 @@ public abstract class AbstractASTWalker implements ASTVisitor{ for(Field f : classOrInterface.getFieldDecl()){ f.accept(this); } + for(Constructor c : classOrInterface.getConstructors()){ + c.accept(this); + } for(Method m : classOrInterface.getMethods()){ m.accept(this); } diff --git a/src/test/java/bytecode/FieldTph.java b/src/test/java/bytecode/FieldTph.java deleted file mode 100644 index 65c7f291..00000000 --- a/src/test/java/bytecode/FieldTph.java +++ /dev/null @@ -1,43 +0,0 @@ -package bytecode; - -import static org.junit.Assert.*; - -import java.io.File; -import java.lang.reflect.Field; -import java.net.URL; -import java.net.URLClassLoader; - -import org.junit.BeforeClass; -import org.junit.Test; - -import de.dhbwstuttgart.core.JavaTXCompiler; - -public class FieldTph { - - 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; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/FieldTph.jav"; - fileToTest = new File(path); - compiler = new JavaTXCompiler(fileToTest); - compiler.generateBytecode(System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"); - pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"; - loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); - classToTest = loader.loadClass("FieldTph"); - instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); - } - - @Test - public void test() { - Field[] fields = classToTest.getFields(); - assertEquals(1, fields.length); - } - -} diff --git a/src/test/java/bytecode/FieldTphConsMethTest.java b/src/test/java/bytecode/FieldTphConsMethTest.java index ecf992d0..382c31e4 100644 --- a/src/test/java/bytecode/FieldTphConsMethTest.java +++ b/src/test/java/bytecode/FieldTphConsMethTest.java @@ -32,11 +32,11 @@ public class FieldTphConsMethTest { pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"; loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); classToTest = loader.loadClass("FieldTphConsMeth"); - instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); } @Test public void test() throws Exception { + instanceOfClass = classToTest.getConstructor(Object.class).newInstance("C"); Field a = classToTest.getDeclaredField("a"); a.setAccessible(true); @@ -44,6 +44,7 @@ public class FieldTphConsMethTest { Object result = m.invoke(instanceOfClass, 42); assertEquals(42,result); + assertEquals("C", a.get(instanceOfClass)); } } diff --git a/src/test/java/bytecode/MatrixOpTest.java b/src/test/java/bytecode/MatrixOpTest.java index 11018701..ea906853 100644 --- a/src/test/java/bytecode/MatrixOpTest.java +++ b/src/test/java/bytecode/MatrixOpTest.java @@ -4,6 +4,7 @@ import static org.junit.Assert.*; import java.io.File; import java.io.IOException; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; @@ -27,7 +28,7 @@ public class MatrixOpTest { private static Object instanceOfClass_m3; @Test - public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IOException, InstantiationException { + public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IOException, InstantiationException, NoSuchFieldException { path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/MatrixOP.jav"; fileToTest = new File(path); compiler = new JavaTXCompiler(fileToTest); @@ -35,7 +36,7 @@ public class MatrixOpTest { compiler.generateBytecode(pathToClassFile); loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); classToTest = loader.loadClass("MatrixOP"); -/* + Vector> vv = new Vector>(); Vector v1 = new Vector (); v1.addElement(2); @@ -48,6 +49,7 @@ public class MatrixOpTest { //m1.addElement(v2); vv.addElement(v1); vv.addElement(v2); + instanceOfClass_m1 = classToTest.getDeclaredConstructor(Vector.class).newInstance(vv); //Matrix m1 = new Matrix(vv); Vector> vv1 = new Vector>(); @@ -62,13 +64,23 @@ public class MatrixOpTest { //m2.addElement(v4); vv1.addElement(v3); vv1.addElement(v4); + instanceOfClass_m2 = classToTest.getDeclaredConstructor(Vector.class).newInstance(vv1);//Matrix m2 = new Matrix(vv1); //Matrix m3 = m1.mul(vv1); - Method mul = classToTest.getDeclaredMethod("mul", Vector.class); - Object result = mul.invoke(instanceOfClass_m1, instanceOfClass_m2); +// Method mul = classToTest.getDeclaredMethod("mul", Vector.class); +// Object result = mul.invoke(instanceOfClass_m1, instanceOfClass_m2); + Field mul = classToTest.getField("mul"); + mul.setAccessible(true); + + Class lambda = mul.get(instanceOfClass_m1).getClass(); + Method apply = lambda.getMethod("apply", Object.class,Object.class); + // Damit man auf die Methode zugreifen kann + apply.setAccessible(true); + + Object result = apply.invoke(mul.get(instanceOfClass_m1),instanceOfClass_m1, instanceOfClass_m2); System.out.println(instanceOfClass_m1.toString() + " * " + instanceOfClass_m2.toString() + " = " + result.toString()); Vector> res = new Vector>(); @@ -85,7 +97,7 @@ public class MatrixOpTest { res.addElement(v6); instanceOfClass_m3 = classToTest.getDeclaredConstructor(Vector.class).newInstance(res); assertEquals(result, instanceOfClass_m3); -*/ + } } diff --git a/src/test/resources/bytecode/javFiles/MatrixOP.jav b/src/test/resources/bytecode/javFiles/MatrixOP.jav index 828a270b..0daef9bd 100644 --- a/src/test/resources/bytecode/javFiles/MatrixOP.jav +++ b/src/test/resources/bytecode/javFiles/MatrixOP.jav @@ -18,7 +18,7 @@ public class MatrixOP extends Vector> { } } - mul = (m1, m2) -> { + public mul = (m1, m2) -> { var ret = new MatrixOP(); var i = 0; while(i < size()) { From fd72ed340d8608d9b74cf05700243e1f56df0f1e Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Thu, 17 Jan 2019 11:26:09 +0100 Subject: [PATCH 02/19] Test Erzeugung Type-Variablen fuer Klassen --- src/test/java/bytecode/FieldTphMMethTest.java | 53 +++++++++++++++++++ .../bytecode/javFiles/FieldTphMMeth.jav | 24 +++++++++ 2 files changed, 77 insertions(+) create mode 100644 src/test/java/bytecode/FieldTphMMethTest.java create mode 100644 src/test/resources/bytecode/javFiles/FieldTphMMeth.jav diff --git a/src/test/java/bytecode/FieldTphMMethTest.java b/src/test/java/bytecode/FieldTphMMethTest.java new file mode 100644 index 00000000..58a9647a --- /dev/null +++ b/src/test/java/bytecode/FieldTphMMethTest.java @@ -0,0 +1,53 @@ +package bytecode; + +import static org.junit.Assert.*; + +import java.io.File; +import java.lang.reflect.Field; +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 FieldTphMMethTest { + + 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; + private static Object instanceOfClass2; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/FieldTphMMeth.jav"; + fileToTest = new File(path); + compiler = new JavaTXCompiler(fileToTest); + compiler.generateBytecode(System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"); + pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"; + loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); + classToTest = loader.loadClass("FieldTphMMeth"); + } + + @Test + public void test() throws Exception { + instanceOfClass = classToTest.getConstructor(Object.class).newInstance("C",42,true); + instanceOfClass2 = classToTest.getConstructor(Object.class).newInstance("C",42,false); + Field a = classToTest.getDeclaredField("a"); + a.setAccessible(true); + + Method m = classToTest.getDeclaredMethod("m", Object.class); + Object result = m.invoke(instanceOfClass, 42); + + assertEquals(42,result); + assertEquals("C", a.get(instanceOfClass)); + assertEquals(42, a.get(instanceOfClass2)); + } + +} diff --git a/src/test/resources/bytecode/javFiles/FieldTphMMeth.jav b/src/test/resources/bytecode/javFiles/FieldTphMMeth.jav new file mode 100644 index 00000000..abc10a46 --- /dev/null +++ b/src/test/resources/bytecode/javFiles/FieldTphMMeth.jav @@ -0,0 +1,24 @@ +public class FieldTphMMeth { + a; + public FieldTphConsMeth(c,d,e) { + a = m(c,d,e); + } + + m(b,d,e) { + if(e) { + return b; + } else{ + m2(d); + } + + } + + m2(b) { + a = m3(b); + } + + m3(b){ + return b; + } + +} \ No newline at end of file From 0a4a625198a784cbb43ec87b5a7474ccb9d397b3 Mon Sep 17 00:00:00 2001 From: Michael Uhl Date: Wed, 23 Jan 2019 22:04:25 +0100 Subject: [PATCH 03/19] Removed "tycho-p2-repository-plugin". --- pom.xml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/pom.xml b/pom.xml index 8ae93bf5..5ef18209 100644 --- a/pom.xml +++ b/pom.xml @@ -139,19 +139,6 @@ - - org.eclipse.tycho - tycho-p2-repository-plugin - ${tycho.version} - - - package - - archive-repository - - - - From e83d59d97d3d1cbda70544b50cb1a70a3642e744 Mon Sep 17 00:00:00 2001 From: Michael Uhl Date: Thu, 24 Jan 2019 11:16:26 +0100 Subject: [PATCH 04/19] =?UTF-8?q?Observer=20Pattern=20f=C3=BCr=20ResultSet?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java | 7 +++++++ .../typeinference/unify/UnifyResultEvent.java | 8 +++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java index f339af1a..d7915f3f 100644 --- a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -33,6 +33,7 @@ import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask; +import de.dhbwstuttgart.typeinference.unify.UnifyResultModel; import java.io.File; import java.io.FileOutputStream; @@ -43,6 +44,8 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.antlr.v4.parse.ANTLRParser.throwsSpec_return; + public class JavaTXCompiler { final CompilationEnvironment environment; @@ -268,6 +271,10 @@ public class JavaTXCompiler { } */ + public UnifyResultModel typeInferenceAsync() throws ClassNotFoundException { + return new UnifyResultModel(); + } + public List typeInference() throws ClassNotFoundException { List allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultEvent.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultEvent.java index 05433287..a79e34ec 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultEvent.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultEvent.java @@ -1,16 +1,18 @@ package de.dhbwstuttgart.typeinference.unify; +import java.util.List; + import de.dhbwstuttgart.typeinference.result.ResultSet; public class UnifyResultEvent { - private ResultSet newTypeResult; + private List newTypeResult; - public UnifyResultEvent(ResultSet newTypeResult) { + public UnifyResultEvent(List newTypeResult) { this.newTypeResult = newTypeResult; } - public ResultSet getNewTypeResult() { + public List getNewTypeResult() { return newTypeResult; } } From 3c0beabc1b1a27855b9279a250be07fccb2399d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Fri, 25 Jan 2019 22:19:32 +0100 Subject: [PATCH 05/19] modified: src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java reduce2 nochmals angepasst modified: src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java - Fehler behoben - In den Thread nur noch Element von nextSet verschieben, die auf alle Faele berechnet werdne muessen --- .../typeinference/unify/RuleSet.java | 3 +- .../typeinference/unify/TypeUnifyTask.java | 47 +++++++++++++++++-- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java index a3430577..a8c0675d 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java @@ -326,7 +326,8 @@ public class RuleSet implements IRuleSet{ lhsSType = (ReferenceType) lhsType; rhsSType = (ReferenceType) rhsType; } - else if ((lhsType instanceof WildcardType) && (rhsType instanceof WildcardType)) { + else if (((lhsType instanceof ExtendsType) && (rhsType instanceof ExtendsType)) + || ((lhsType instanceof SuperType) && (rhsType instanceof SuperType))) { UnifyType lhsSTypeRaw = ((WildcardType) lhsType).getWildcardedType(); UnifyType rhsSTypeRaw = ((WildcardType) rhsType).getWildcardedType(); if ((lhsSTypeRaw instanceof ReferenceType) && (rhsSTypeRaw instanceof ReferenceType)) { diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java index 8b2c7c3c..da3d508b 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java @@ -810,6 +810,23 @@ public class TypeUnifyTask extends RecursiveTask>> { nextSetasListRest.remove(a_next); } } + //Alle maximale Elemente in nextSetasListRest bestimmen + List> nextSetasListRestTest; + do { + nextSetasListRestTest = new ArrayList>(nextSetasListRest); + if (!nextSetasListRest.isEmpty()) { + Set max = oup.max(nextSetasListRest.iterator()); + Iterator> nextSetasListItRest2 = new ArrayList>(nextSetasListRest).iterator(); + while (nextSetasListItRest2.hasNext()) { + Set a_nextRest = nextSetasListItRest2.next(); + if (//a.equals(a_next) || + (oup.compare(max, a_nextRest) == 1)) { + nextSetasListRest.remove(a_nextRest); + } + + }} + } while(!nextSetasListRestTest.equals(nextSetasListRest)); + } else if (variance == -1) { a = oup.min(nextSetasList.iterator()); @@ -823,6 +840,23 @@ public class TypeUnifyTask extends RecursiveTask>> { nextSetasListRest.remove(a_next); } } + //Alle minimalen Elemente in nextSetasListRest bestimmen + + List> nextSetasListRestTest; + do { + nextSetasListRestTest = new ArrayList>(nextSetasListRest); + if (!nextSetasListRest.isEmpty()) { + Set min = oup.min(nextSetasListRest.iterator()); + Iterator> nextSetasListItRest2 = new ArrayList>(nextSetasListRest).iterator(); + while (nextSetasListItRest2.hasNext()) { + Set a_nextRest = nextSetasListItRest2.next(); + if (//a.equals(a_next) || + (oup.compare(min, a_nextRest) == -1)) { + nextSetasListRest.remove(a_nextRest); + } + + }} + } while(!nextSetasListRestTest.equals(nextSetasListRest)); } else if (variance == 2) { a = nextSetasList.remove(0); @@ -1860,13 +1894,17 @@ public class TypeUnifyTask extends RecursiveTask>> { for(UnifyType c : csPHRenamed) { //PL 18-02-05 getChildren durch smaller ersetzt in getChildren werden die Varianlen nicht ersetzt. - Set thetaQs = fc.smaller(c, new HashSet<>()).stream().collect(Collectors.toCollection(HashSet::new)); + Set thetaQs = new HashSet<>(); + //TODO smaller wieder reinnehmen? + //thetaQs.add(c);// + thetaQs = fc.smaller(c, new HashSet<>()).stream().collect(Collectors.toCollection(HashSet::new)); //Set thetaQs = fc.getChildren(c).stream().collect(Collectors.toCollection(HashSet::new)); //thetaQs.add(thetaPrime); //PL 18-02-05 wieder geloescht //PL 2017-10-03: War auskommentiert habe ich wieder einkommentiert, //da children offensichtlich ein echtes kleiner und kein kleinergleich ist //PL 18-02-06: eingefuegt, thetaQs der Form V> <. V'> werden entfernt + //TODO PL 19-01-14 wieder reinnehmen kurzfristig auskommentiert thetaQs = thetaQs.stream().filter(ut -> ut.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new)); //PL 18-02-06: eingefuegt @@ -1931,13 +1969,16 @@ public class TypeUnifyTask extends RecursiveTask>> { if(allGen) { UnifyPair up = new UnifyPair(a, theta, PairOperator.EQUALSDOT, pair.getSubstitution(), pair); Iterator upit = up.getRhsType().getTypeParams().iterator(); - while (upit.hasNext()) ((PlaceholderType)upit.next()).setVariance(a.getVariance()); + //TODO PL 2019-01-24: upit.next() ist nicht unbedingt ein PlaceholderType -> Visitor + while (upit.hasNext()) upit.next().accept(new distributeVariance(), a.getVariance());//((PlaceholderType)upit.next()).setVariance(a.getVariance()); resultPrime.add(up); } else { UnifyPair up = new UnifyPair(a, theta.setTypeParams(new TypeParams(freshTphs.toArray(new UnifyType[0]))), PairOperator.EQUALSDOT, pair.getSubstitution(), pair); Iterator upit = up.getRhsType().getTypeParams().iterator(); - while (upit.hasNext()) ((PlaceholderType)upit.next()).setVariance(a.getVariance()); + distributeVariance dv = new distributeVariance(); + //TODO PL 2019-01-24: upit.next() ist nicht unbedingt ein PlaceholderType -> Visitor + while (upit.hasNext()) upit.next().accept(new distributeVariance(), a.getVariance()); //((PlaceholderType)upit.next()).setVariance(a.getVariance()); resultPrime.add(up); } resultPrime.addAll(substitutionSet); From 9dcb1f76cab606a7356b4baaa3a5590d8a9fb427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Fri, 25 Jan 2019 22:22:16 +0100 Subject: [PATCH 06/19] modified: src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java --- .../de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java index a5919c18..dc600939 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java @@ -17,7 +17,7 @@ public class UnifyResultModel { listeners.remove(listenerToRemove); } - public void notify(ResultSet newResult) { + public void notify(Set newResult) { UnifyResultEvent evt = new UnifyResultEvent(newResult); for (UnifyResultListener listener : listeners) { From 26634bb03842b55e9884b85c01d65ceb911e310e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Fri, 25 Jan 2019 22:26:38 +0100 Subject: [PATCH 07/19] modified: src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java --- .../de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java index dc600939..fe72bfea 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java @@ -2,6 +2,7 @@ package de.dhbwstuttgart.typeinference.unify; import java.util.ArrayList; import java.util.List; +import java.util.Set; import de.dhbwstuttgart.typeinference.result.ResultSet; @@ -17,7 +18,7 @@ public class UnifyResultModel { listeners.remove(listenerToRemove); } - public void notify(Set newResult) { + public void notify(List newResult) { UnifyResultEvent evt = new UnifyResultEvent(newResult); for (UnifyResultListener listener : listeners) { From ca7c76a99af59c6fc6eb3fd6886c6721391e258e Mon Sep 17 00:00:00 2001 From: Pluemicke Martin Date: Tue, 29 Jan 2019 14:47:20 +0100 Subject: [PATCH 08/19] =?UTF-8?q?=09ge=C3=A4ndert:=20=20=20=20=20=20=20src?= =?UTF-8?q?/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java=20=09ge?= =?UTF-8?q?=C3=A4ndert:=20=20=20=20=20=20=20src/main/java/de/dhbwstuttgart?= =?UTF-8?q?/typeinference/constraints/ConstraintSet.java=20=09ge=C3=A4nder?= =?UTF-8?q?t:=20=20=20=20=20=20=20src/main/java/de/dhbwstuttgart/typeinfer?= =?UTF-8?q?ence/constraints/Pair.java=20=09ge=C3=A4ndert:=20=20=20=20=20?= =?UTF-8?q?=20=20src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUn?= =?UTF-8?q?ify.java=20=09ge=C3=A4ndert:=20=20=20=20=20=20=20src/main/java/?= =?UTF-8?q?de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java=20=09g?= =?UTF-8?q?e=C3=A4ndert:=20=20=20=20=20=20=20src/main/java/de/dhbwstuttgar?= =?UTF-8?q?t/typeinference/unify/TypeUnifyTask.java=20=09ge=C3=A4ndert:=20?= =?UTF-8?q?=20=20=20=20=20=20src/main/java/de/dhbwstuttgart/typeinference/?= =?UTF-8?q?unify/UnifyResultModel.java?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../de/dhbwstuttgart/core/JavaTXCompiler.java | 24 +++++------------ .../constraints/ConstraintSet.java | 1 + .../typeinference/constraints/Pair.java | 18 +++++++++++++ .../typeinference/unify/TypeUnify.java | 19 ++++++++++--- .../typeinference/unify/TypeUnify2Task.java | 6 +++-- .../typeinference/unify/TypeUnifyTask.java | 27 ++++++++++++++++--- .../typeinference/unify/UnifyResultModel.java | 2 +- 7 files changed, 69 insertions(+), 28 deletions(-) diff --git a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java index d7915f3f..5a749dcc 100644 --- a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -27,6 +27,7 @@ import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; import de.dhbwstuttgart.typeinference.unify.RuleSet; import de.dhbwstuttgart.typeinference.unify.TypeUnify; import de.dhbwstuttgart.typeinference.unify.distributeVariance; +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; @@ -289,7 +290,7 @@ public class JavaTXCompiler { try { FileWriter logFile = new FileWriter(new File(System.getProperty("user.dir")+"/src/test/java/logFiles/"+"log_"+sourceFiles.keySet().iterator().next().getName())); - FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses,logFile); + IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses,logFile); System.out.println(finiteClosure); ConstraintSet unifyCons = UnifyTypeFactory.convert(cons); @@ -402,8 +403,9 @@ public class JavaTXCompiler { } return ret; }).collect(Collectors.toCollection(ArrayList::new)); - Set> result = unify.unify(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log); - //Set> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log); + unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons); + Set> result = unify.unify(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons); + //Set> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons); System.out.println("RESULT: " + result); logFile.write("RES: " + result.toString()+"\n"); logFile.flush(); @@ -430,7 +432,7 @@ public class JavaTXCompiler { System.err.println("kein LogFile"); } return results.stream().map((unifyPairs -> - new ResultSet(UnifyTypeFactory.convert(unifyPairs, generateTPHMap(cons))))).collect(Collectors.toList()); + new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList()); } @@ -479,19 +481,7 @@ public class JavaTXCompiler { } - private Map generateTPHMap(ConstraintSet constraints) { - HashMap ret = new HashMap<>(); - constraints.map((Pair p) -> { - if (p.TA1 instanceof TypePlaceholder) { - ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1); - } - if (p.TA2 instanceof TypePlaceholder) { - ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2); - } - return null; - }); - return ret; - } + private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException { CompilationUnitContext tree = JavaTXParser.parse(sourceFile); diff --git a/src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSet.java b/src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSet.java index 4d1f076f..1dda8dc5 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSet.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSet.java @@ -1,6 +1,7 @@ package de.dhbwstuttgart.typeinference.constraints; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.unify.GuavaSetOperations; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; diff --git a/src/main/java/de/dhbwstuttgart/typeinference/constraints/Pair.java b/src/main/java/de/dhbwstuttgart/typeinference/constraints/Pair.java index 98679f7d..0c8ad7a5 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/constraints/Pair.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/constraints/Pair.java @@ -1,7 +1,10 @@ package de.dhbwstuttgart.typeinference.constraints; import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.unify.model.PairOperator; @@ -110,5 +113,20 @@ public class Pair implements Serializable public boolean OperatorSmallerDot() { return eOperator == PairOperator.SMALLERDOT; } + + + static public Map generateTPHMap(ConstraintSet constraints) { + HashMap ret = new HashMap<>(); + constraints.map((Pair p) -> { + if (p.TA1 instanceof TypePlaceholder) { + ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1); + } + if (p.TA2 instanceof TypePlaceholder) { + ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2); + } + return null; + }); + return ret; + } } // ino.end diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java index fecd28fe..aa7fe5ea 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java @@ -6,18 +6,29 @@ import java.util.Set; import java.util.concurrent.ForkJoinPool; import de.dhbwstuttgart.typeinference.constraints.Constraint; +import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; +import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; +import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; public class TypeUnify { - public Set> unify(Set undConstrains, List>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log) { - TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0); + public Set> unify(Set undConstrains, List>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet cons) { + TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, new UnifyResultModel(), cons); ForkJoinPool pool = new ForkJoinPool(); pool.invoke(unifyTask); Set> res = unifyTask.join(); return res; } + public UnifyResultModel unifyParallel(Set undConstrains, List>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet cons) { + UnifyResultModel ret = new UnifyResultModel(); + TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, cons); + ForkJoinPool pool = new ForkJoinPool(); + pool.invoke(unifyTask); + return ret; + } + /* public Set> unifySequential(Set eq, IFiniteClosure fc, FileWriter logFile, Boolean log) { TypeUnifyTask unifyTask = new TypeUnifyTask(eq, fc, false, logFile, log); @@ -26,8 +37,8 @@ public class TypeUnify { } */ - public Set> unifyOderConstraints(Set undConstrains, List>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log) { - TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, false, logFile, log, 0); + public Set> unifyOderConstraints(Set undConstrains, List>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet cons) { + TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, false, logFile, log, 0, new UnifyResultModel(), cons); Set> res = unifyTask.compute(); return res; } diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java index 95ccdf07..7c0a587d 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.Set; import de.dhbwstuttgart.typeinference.constraints.Constraint; +import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; +import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; @@ -13,8 +15,8 @@ public class TypeUnify2Task extends TypeUnifyTask { Set> setToFlatten; - public TypeUnify2Task(Set> setToFlatten, Set eq, List>> oderConstraints, IFiniteClosure fc, boolean parallel, FileWriter logFile, Boolean log, int rekTiefe) { - super(eq, oderConstraints, fc, parallel, logFile, log, rekTiefe); + public TypeUnify2Task(Set> setToFlatten, Set eq, List>> oderConstraints, IFiniteClosure fc, boolean parallel, FileWriter logFile, Boolean log, int rekTiefe, UnifyResultModel urm, ConstraintSet cons) { + super(eq, oderConstraints, fc, parallel, logFile, log, rekTiefe, urm, cons); this.setToFlatten = setToFlatten; } diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java index 8b2c7c3c..5b043b27 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java @@ -19,7 +19,10 @@ import java.util.function.BinaryOperator; import java.util.stream.Collectors; import java.util.stream.Stream; +import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; import de.dhbwstuttgart.typeinference.constraints.Constraint; +import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; +import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations; @@ -59,6 +62,8 @@ public class TypeUnifyTask extends RecursiveTask>> { /** * Fuer die Threads */ + UnifyResultModel urm; + ConstraintSet cons; private static int noOfThread = 0; private static int totalnoOfThread = 0; int thNo; @@ -123,7 +128,7 @@ public class TypeUnifyTask extends RecursiveTask>> { } */ - public TypeUnifyTask(Set eq, List>> oderConstraints, IFiniteClosure fc, boolean parallel, FileWriter logFile, Boolean log, int rekTiefe) { + public TypeUnifyTask(Set eq, List>> oderConstraints, IFiniteClosure fc, boolean parallel, FileWriter logFile, Boolean log, int rekTiefe, UnifyResultModel urm, ConstraintSet cons2) { synchronized (this) { this.eq = eq; //this.oderConstraints = oderConstraints.stream().map(x -> x.stream().map(y -> new HashSet<>(y)).collect(Collectors.toSet(HashSet::new))).collect(Collectors.toList(ArrayList::new)); @@ -144,6 +149,8 @@ public class TypeUnifyTask extends RecursiveTask>> { this.log = log; rules = new RuleSet(logFile); this.rekTiefeField = rekTiefe; + this.urm = urm; + this.cons = cons2; noOfThread++; totalnoOfThread++; @@ -688,6 +695,18 @@ public class TypeUnifyTask extends RecursiveTask>> { System.err.println("log-File nicht vorhanden"); } eqPrimePrimeSet.add(eqPrime); + Set> eqPrimePrimeSetRet = eqPrimePrimeSet.stream().map(x -> { + Optional> res = new RuleSet().subst(x.stream().map(y -> { + if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT); + return y; //alle Paare a <.? b erden durch a =. b ersetzt + }).collect(Collectors.toCollection(HashSet::new))); + if (res.isPresent()) {//wenn subst ein Erg liefert wurde was veraendert + return new TypeUnifyTask().applyTypeUnificationRules(res.get(), fc); + } + else return x; //wenn nichts veraendert wurde wird x zurueckgegeben + }).collect(Collectors.toCollection(HashSet::new)); + urm.notify(eqPrimePrimeSetRet.stream().map((unifyPairs -> + new ResultSet(UnifyTypeFactory.convert(unifyPairs, de.dhbwstuttgart.typeinference.constraints.Pair.generateTPHMap(cons))))).collect(Collectors.toList())); } else if(eqPrimePrime.isPresent()) { Set> unifyres = unifyres1 = unify(eqPrimePrime.get(), oderConstraints, fc, parallel, rekTiefe); @@ -901,7 +920,7 @@ public class TypeUnifyTask extends RecursiveTask>> { Set> newElems = new HashSet<>(elems); List>> newOderConstraints = new ArrayList<>(oderConstraints); newElems.add(nSaL); - TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, fc, parallel, logFile, log, rekTiefe); + TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, fc, parallel, logFile, log, rekTiefe, urm, cons); forks.add(fork); fork.fork(); } @@ -952,7 +971,7 @@ public class TypeUnifyTask extends RecursiveTask>> { Set> newElems = new HashSet<>(elems); List>> newOderConstraints = new ArrayList<>(oderConstraints); newElems.add(nSaL); - TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, fc, parallel, logFile, log, rekTiefe); + TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, fc, parallel, logFile, log, rekTiefe, urm, cons); forks.add(fork); fork.fork(); } @@ -1002,7 +1021,7 @@ public class TypeUnifyTask extends RecursiveTask>> { Set> newElems = new HashSet<>(elems); List>> newOderConstraints = new ArrayList<>(oderConstraints); newElems.add(nSaL); - TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, fc, parallel, logFile, log, rekTiefe); + TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, fc, parallel, logFile, log, rekTiefe, urm, cons); forks.add(fork); fork.fork(); } diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java index a5919c18..fc04c8e7 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java @@ -17,7 +17,7 @@ public class UnifyResultModel { listeners.remove(listenerToRemove); } - public void notify(ResultSet newResult) { + public void notify(List newResult) { UnifyResultEvent evt = new UnifyResultEvent(newResult); for (UnifyResultListener listener : listeners) { From 9e1d58f4b17e1a6ffc82971674ec6e18ac452860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Tue, 29 Jan 2019 14:51:19 +0100 Subject: [PATCH 09/19] modified: src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java modified: src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java modified: src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java modified: src/main/java/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java Threads soweit fertig --- .../typeinference/unify/TypeUnify2Task.java | 1 + .../typeinference/unify/TypeUnifyTask.java | 60 ++++++++----------- .../unify/model/FiniteClosure.java | 29 ++++++++- .../unify/model/OrderingUnifyPair.java | 2 +- 4 files changed, 54 insertions(+), 38 deletions(-) diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java index 95ccdf07..a8f446c9 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java @@ -29,6 +29,7 @@ public class TypeUnify2Task extends TypeUnifyTask { return new HashSet<>(); } else */ + noOfThread--; return res; } } diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java index da3d508b..acbabdd2 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java @@ -59,11 +59,11 @@ public class TypeUnifyTask extends RecursiveTask>> { /** * Fuer die Threads */ - private static int noOfThread = 0; + protected static int noOfThread = 0; private static int totalnoOfThread = 0; int thNo; protected boolean one = false; - Integer MaxNoOfThreads = 4; + Integer MaxNoOfThreads = 8; public static final String rootDirectory = System.getProperty("user.dir")+"/test/logFiles/"; FileWriter logFile; @@ -200,6 +200,7 @@ public class TypeUnifyTask extends RecursiveTask>> { .filter(x -> x.size()>1) .collect(Collectors.toCollection(ArrayList::new)); Set> res = unify(neweq, remainingOderconstraints, fc, parallel, rekTiefeField); + noOfThread--; if (isUndefinedPairSetSet(res)) { return new HashSet<>(); } else return res; } @@ -891,7 +892,7 @@ public class TypeUnifyTask extends RecursiveTask>> { //for(Set a : newSet) { i++; Set> elems = new HashSet>(fstElems); - writeLog("a1: " + rekTiefe + " "+ a.toString()+ "\n"); + writeLog("a1: " + rekTiefe + " "+ "variance: "+ variance + " " + a.toString()+ "\n"); //elems.add(a); PL 2019-01-20 Muss weg, weil das in jeweiligen Thread erfolgen muss. Fuer den sequentiellen Fall //im else-Zweig //if (remainingSets.isEmpty()) {//muss immer gegeben sein, weil nur 1 Element der topLevelSets mehr als ein Elemet enthaelt @@ -899,28 +900,17 @@ public class TypeUnifyTask extends RecursiveTask>> { Set> res = new HashSet<>(); Set>> add_res = new HashSet<>(); if(parallel && (variance == 1) && noOfThread <= MaxNoOfThreads) { - /* - elems.add(a); - TypeUnify2Task fork = new TypeUnify2Task(elems, eq, fc, parallel, logFile, log); - fork.fork(); - res = fork.join(); - */ - Set forks = new HashSet<>(); - - //TypeUnify2Task fork1 = new TypeUnify2Task(elems, eq, fc, parallel, logFile, log); - - Set newEqOrig = new HashSet<>(eq); Set> newElemsOrig = new HashSet<>(elems); List>> newOderConstraintsOrig = new ArrayList<>(oderConstraints); newElemsOrig.add(a); - /* FORK ANFANG + /* FORK ANFANG */ TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, logFile, log, rekTiefe); //forks.add(forkOrig); forkOrig.fork(); - FORK ENDE */ + /* FORK ENDE */ synchronized (this) { writeLog("a in " + variance + " "+ a); @@ -939,23 +929,23 @@ public class TypeUnifyTask extends RecursiveTask>> { forks.add(fork); fork.fork(); } - res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe); + //res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe); - /* FORK ANFANG + /* FORK ANFANG */ synchronized (this) { res = forkOrig.join(); //Set> fork_res = forkOrig.join(); writeLog("JoinOrig " + new Integer(forkOrig.thNo).toString()); - noOfThread--; + //noOfThread--; an das Ende von compute verschoben //add_res.add(fork_res); }; - FORK ENDE */ + /* FORK ENDE */ for(TypeUnifyTask fork : forks) { synchronized (this) { Set> fork_res = fork.join(); writeLog("Join " + new Integer(fork.thNo).toString()); - noOfThread--; + //noOfThread--; an das Ende von compute verschoben add_res.add(fork_res); }; } @@ -967,11 +957,11 @@ public class TypeUnifyTask extends RecursiveTask>> { List>> newOderConstraintsOrig = new ArrayList<>(oderConstraints); newElemsOrig.add(a); - /* FORK ANFANG + /* FORK ANFANG */ TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, logFile, log, rekTiefe); //forks.add(forkOrig); forkOrig.fork(); - FORK ENDE */ + /* FORK ENDE */ synchronized (this) { writeLog("a in " + variance + " "+ a); @@ -990,23 +980,23 @@ public class TypeUnifyTask extends RecursiveTask>> { forks.add(fork); fork.fork(); } - res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe); + //res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe); - /* FORK ANFANG + /* FORK ANFANG */ synchronized (this) { res = forkOrig.join(); //Set> fork_res = forkOrig.join(); writeLog("JoinOrig " + new Integer(forkOrig.thNo).toString()); - noOfThread--; + //noOfThread--; an das Ende von compute verschoben //add_res.add(fork_res); }; - FORK ENDE */ + /* FORK ENDE */ for(TypeUnifyTask fork : forks) { synchronized (this) { Set> fork_res = fork.join(); writeLog("Join " + new Integer(fork.thNo).toString()); - noOfThread--; + //noOfThread--; an das Ende von compute verschoben add_res.add(fork_res); }; } @@ -1019,11 +1009,11 @@ public class TypeUnifyTask extends RecursiveTask>> { List>> newOderConstraintsOrig = new ArrayList<>(oderConstraints); newElemsOrig.add(a); - /* FORK ANFANG + /* FORK ANFANG */ TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, logFile, log, rekTiefe); //forks.add(forkOrig); forkOrig.fork(); - FORK ENDE */ + /* FORK ENDE */ synchronized (this) { writeLog("a in " + variance + " "+ a); @@ -1040,23 +1030,23 @@ public class TypeUnifyTask extends RecursiveTask>> { forks.add(fork); fork.fork(); } - res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe); + //res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe); - /* FORK ANFANG + /* FORK ANFANG */ synchronized (this) { res = forkOrig.join(); //Set> fork_res = forkOrig.join(); writeLog("JoinOrig " + new Integer(forkOrig.thNo).toString()); - noOfThread--; + //noOfThread--; an das Ende von compute verschoben //add_res.add(fork_res); //vermutlich falsch }; - FORK ENDE */ + /* FORK ENDE */ for(TypeUnifyTask fork : forks) { synchronized (this) { Set> fork_res = fork.join(); writeLog("Join " + new Integer(fork.thNo).toString()); - noOfThread--; + //noOfThread--; an das Ende von compute verschoben add_res.add(fork_res); }; }} diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 07c86457..c52f47a7 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -109,6 +109,18 @@ implements IFiniteClosure { strInheritanceGraph.get(key.getName()).add(inheritanceGraph.get(key)); } } + + void testSmaller() { + UnifyType tq1, tq2, tq3; + tq1 = new ExtendsType(PlaceholderType.freshPlaceholder()); + List l1 = new ArrayList<>(); + List l2 = new ArrayList<>(); + l1.add(tq1); + tq2 = new ReferenceType("java.util.Vector", new TypeParams(l1)); + l2.add(tq2); + tq3 = new ReferenceType("java.util.Vector", new TypeParams(l2)); + Set smaller = smaller(tq3, new HashSet<>()); + } /** * Returns all types of the finite closure that are subtypes of the argument. @@ -641,8 +653,7 @@ implements IFiniteClosure { */ public int compare (UnifyType left, UnifyType right, PairOperator pairop) { - if ((left instanceof ExtendsType && right instanceof ReferenceType) - || (right instanceof ExtendsType && left instanceof ReferenceType)) + if (left.getName().equals("Matrix") || right.getName().equals("Matrix")) System.out.println(""); /* List al = new ArrayList<>(); @@ -693,6 +704,13 @@ implements IFiniteClosure { HashSet hs = new HashSet<>(); hs.add(up); Set smallerRes = unifyTask.applyTypeUnificationRules(hs, this); + if (left.getName().equals("Matrix") || right.getName().equals("Matrix")) + {try { + logFile.write("\nsmallerRes: " + smallerRes);//"smallerHash: " + greaterHash.toString()); + logFile.flush(); + } + catch (IOException e) { + System.err.println("no LogFile");}} //Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok. long smallerLen = smallerRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)).count(); if (smallerLen == 0) return -1; @@ -702,6 +720,13 @@ implements IFiniteClosure { hs = new HashSet<>(); hs.add(up); Set greaterRes = unifyTask.applyTypeUnificationRules(hs, this); + if (left.getName().equals("Matrix") || right.getName().equals("Matrix")) + {try { + logFile.write("\ngreaterRes: " + greaterRes);//"smallerHash: " + greaterHash.toString()); + logFile.flush(); + } + catch (IOException e) { + System.err.println("no LogFile");}} //Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok. long greaterLen = greaterRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)).count(); if (greaterLen == 0) return 1; diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java index 73d73578..490826cc 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java @@ -229,7 +229,7 @@ public class OrderingUnifyPair extends Ordering> { if (leftlewc.iterator().next().getLhsType() instanceof PlaceholderType) { hm = rsleuni.stream().reduce(new HashMap(), (x, y)-> { x.put(y.getLhsType(),y); return x; }, combiner); Stream lslewcstr = lsleuni.stream().filter(x -> !(hm.get(x.getLhsType()) == null)); - si = lslewcstr.map(x -> fc.compare(x.getRhsType(), hm.get(x.getLhsType()).getRhsType(), PairOperator.SMALLERDOTWC)).reduce((x,y)-> { if (x == y) return x; else return 0; } ); + si = lslewcstr.map(x -> fc.compare(x.getRhsType(), hm.get(x.getLhsType()).getRhsType(), PairOperator.SMALLERDOTWC)).reduce((x,y)-> { if (x == y) return x; else return 0; } ); } //4. Fall else { From aa0b1573743b0aa73b8473c7184ca7b686d6fb20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Wed, 30 Jan 2019 09:11:33 +0100 Subject: [PATCH 10/19] modified: src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java modified: src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java modified: src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java new file: src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListenerImpl.java modified: src/test/resources/bytecode/javFiles/MatrixOP.jav Erster Ansatz asyncrone Threads --- .../de/dhbwstuttgart/core/JavaTXCompiler.java | 73 +++++++++++-------- .../typeinference/unify/TypeUnify.java | 11 ++- .../typeinference/unify/TypeUnifyTask.java | 17 +++-- .../unify/UnifyResultListenerImpl.java | 21 ++++++ .../resources/bytecode/javFiles/MatrixOP.jav | 2 +- 5 files changed, 84 insertions(+), 40 deletions(-) create mode 100644 src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListenerImpl.java diff --git a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java index 5a749dcc..b9d1da90 100644 --- a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -34,6 +34,7 @@ import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask; +import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl; import de.dhbwstuttgart.typeinference.unify.UnifyResultModel; import java.io.File; @@ -50,6 +51,7 @@ import org.antlr.v4.parse.ANTLRParser.throwsSpec_return; public class JavaTXCompiler { final CompilationEnvironment environment; + Boolean resultmodel = true; public final Map sourceFiles = new HashMap<>(); Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+"src/test/java/logFiles" geschrieben werden soll? @@ -403,37 +405,50 @@ public class JavaTXCompiler { } return ret; }).collect(Collectors.toCollection(ArrayList::new)); - unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons); - Set> result = unify.unify(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons); - //Set> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons); - System.out.println("RESULT: " + result); - logFile.write("RES: " + result.toString()+"\n"); - logFile.flush(); - results.addAll(result); + if (resultmodel) { + /* UnifyResultModel Anfang */ + UnifyResultModel urm = new UnifyResultModel(); + UnifyResultListenerImpl li = new UnifyResultListenerImpl(); + urm.addUnifyResultListener(li); + unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons, urm); + System.out.println("RESULT Final: " + li.getResults()); + logFile.write("RES_FINAL: " + li.getResults().toString()+"\n"); + logFile.flush(); + return li.getResults(); + } + /* UnifyResultModel End */ + else { + Set> result = unify.unify(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons); + //Set> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons); + System.out.println("RESULT: " + result); + logFile.write("RES: " + result.toString()+"\n"); + logFile.flush(); + results.addAll(result); - results = results.stream().map(x -> { - Optional> res = new RuleSet().subst(x.stream().map(y -> { - if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT); - return y; //alle Paare a <.? b erden durch a =. b ersetzt - }).collect(Collectors.toCollection(HashSet::new))); - if (res.isPresent()) {//wenn subst ein Erg liefert wurde was veraendert - return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure); - } - else return x; //wenn nichts veraendert wurde wird x zurueckgegeben - }).collect(Collectors.toCollection(HashSet::new)); - System.out.println("RESULT Final: " + results); - logFile.write("RES_FINAL: " + results.toString()+"\n"); - logFile.flush(); - logFile.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS); - logFile.flush(); - } - catch (IOException e) { - System.err.println("kein LogFile"); - } - return results.stream().map((unifyPairs -> - new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList()); - } + results = results.stream().map(x -> { + Optional> res = new RuleSet().subst(x.stream().map(y -> { + if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT); + return y; //alle Paare a <.? b erden durch a =. b ersetzt + }).collect(Collectors.toCollection(HashSet::new))); + if (res.isPresent()) {//wenn subst ein Erg liefert wurde was veraendert + return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure); + } + else return x; //wenn nichts veraendert wurde wird x zurueckgegeben + }).collect(Collectors.toCollection(HashSet::new)); + System.out.println("RESULT Final: " + results); + logFile.write("RES_FINAL: " + results.toString()+"\n"); + logFile.flush(); + logFile.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS); + logFile.flush(); + }} + catch (IOException e) { + System.err.println("kein LogFile"); + } + return results.stream().map((unifyPairs -> + new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList()); + } + /** diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java index aa7fe5ea..d1fc2afe 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java @@ -21,14 +21,21 @@ public class TypeUnify { return res; } - public UnifyResultModel unifyParallel(Set undConstrains, List>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet cons) { - UnifyResultModel ret = new UnifyResultModel(); + public UnifyResultModel unifyAsync(Set undConstrains, List>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet cons, UnifyResultModel ret) { TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, cons); ForkJoinPool pool = new ForkJoinPool(); pool.invoke(unifyTask); return ret; } + public UnifyResultModel unifyParallel(Set undConstrains, List>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet cons, UnifyResultModel ret) { + TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, cons); + ForkJoinPool pool = new ForkJoinPool(); + pool.invoke(unifyTask); + Set> res = unifyTask.join(); + return ret; + } + /* public Set> unifySequential(Set eq, IFiniteClosure fc, FileWriter logFile, Boolean log) { TypeUnifyTask unifyTask = new TypeUnifyTask(eq, fc, false, logFile, log); diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java index 904959bb..d8588ae4 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java @@ -926,7 +926,7 @@ public class TypeUnifyTask extends RecursiveTask>> { newElemsOrig.add(a); /* FORK ANFANG */ - TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, logFile, log, rekTiefe); + TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, logFile, log, rekTiefe, urm, cons); //forks.add(forkOrig); forkOrig.fork(); /* FORK ENDE */ @@ -977,7 +977,7 @@ public class TypeUnifyTask extends RecursiveTask>> { newElemsOrig.add(a); /* FORK ANFANG */ - TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, logFile, log, rekTiefe); + TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, logFile, log, rekTiefe, urm, cons); //forks.add(forkOrig); forkOrig.fork(); /* FORK ENDE */ @@ -1029,7 +1029,7 @@ public class TypeUnifyTask extends RecursiveTask>> { newElemsOrig.add(a); /* FORK ANFANG */ - TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, logFile, log, rekTiefe); + TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, logFile, log, rekTiefe, urm, cons); //forks.add(forkOrig); forkOrig.fork(); /* FORK ENDE */ @@ -1878,12 +1878,13 @@ public class TypeUnifyTask extends RecursiveTask>> { allGen = false; break; } - //if (thetaPrime.getName().equals("java.util.Vector") //Fuer Bug 127 - // && thetaPrime instanceof ReferenceType - // && ((ReferenceType)thetaPrime).getTypeParams().iterator().next().getName().equals("java.util.Vector") + if (thetaPrime.getName().equals("java.util.Vector") //Fuer Bug 127 + && thetaPrime instanceof ReferenceType + && ((ReferenceType)thetaPrime).getTypeParams().iterator().next().getName().equals("java.util.Vector")) // && ((ReferenceType)((ReferenceType)thetaPrime).getTypeParams().iterator().next()).getTypeParams().iterator().next().getName().equals("java.lang.Integer")) { - // System.out.println(""); - //} + { + System.out.println(""); + } Set cs = fc.getAllTypesByName(thetaPrime.getName());//cs= [java.util.Vector, java.util.Vector>, ????java.util.Vector???] diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListenerImpl.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListenerImpl.java new file mode 100644 index 00000000..16133a3f --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListenerImpl.java @@ -0,0 +1,21 @@ +package de.dhbwstuttgart.typeinference.unify; + +import java.util.ArrayList; +import java.util.List; + +import de.dhbwstuttgart.typeinference.result.ResultSet; +import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; + +public class UnifyResultListenerImpl implements UnifyResultListener { + + List results = new ArrayList<>(); + + public void onNewTypeResultFound(UnifyResultEvent evt) { + results.addAll(evt.getNewTypeResult()); + } + + public List getResults() { + return results; + } + +} diff --git a/src/test/resources/bytecode/javFiles/MatrixOP.jav b/src/test/resources/bytecode/javFiles/MatrixOP.jav index c78c42c7..828a270b 100644 --- a/src/test/resources/bytecode/javFiles/MatrixOP.jav +++ b/src/test/resources/bytecode/javFiles/MatrixOP.jav @@ -1,6 +1,6 @@ import java.util.Vector; import java.lang.Integer; -import java.lang.Byte; +//import java.lang.Byte; import java.lang.Boolean; public class MatrixOP extends Vector> { From 33f2bf3d217a94a16f43d82cb167bb419736bbe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Thu, 31 Jan 2019 15:08:36 +0100 Subject: [PATCH 11/19] modified: src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java modified: src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java modified: src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListenerImpl.java Asynchrone Variante soweit ok --- .../de/dhbwstuttgart/core/JavaTXCompiler.java | 133 +++++++++++++++++- .../typeinference/unify/TypeUnifyTask.java | 16 +-- .../unify/UnifyResultListenerImpl.java | 2 +- 3 files changed, 141 insertions(+), 10 deletions(-) diff --git a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java index b9d1da90..2c19d8b3 100644 --- a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -275,7 +275,138 @@ public class JavaTXCompiler { */ public UnifyResultModel typeInferenceAsync() throws ClassNotFoundException { - return new UnifyResultModel(); + List allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); + //Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC + for(SourceFile sf : this.sourceFiles.values()) { + allClasses.addAll(getAvailableClasses(sf)); + allClasses.addAll(sf.getClasses()); + } + + final ConstraintSet cons = getConstraints(); + Set> results = new HashSet<>(); + UnifyResultModel urm = new UnifyResultModel(); + try { + FileWriter logFile = new FileWriter(new File(System.getProperty("user.dir")+"/src/test/java/logFiles/"+"log_"+sourceFiles.keySet().iterator().next().getName())); + + IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses,logFile); + System.out.println(finiteClosure); + ConstraintSet unifyCons = UnifyTypeFactory.convert(cons); + + Function distributeInnerVars = + x -> { + UnifyType lhs, rhs; + if (((lhs = x.getLhsType()) instanceof PlaceholderType) + && ((rhs = x.getRhsType()) instanceof PlaceholderType) + && (((PlaceholderType)lhs).isInnerType() + || ((PlaceholderType)rhs).isInnerType())) + { + ((PlaceholderType)lhs).setInnerType(true); + ((PlaceholderType)rhs).setInnerType(true); + } + return x; + + }; + logFile.write(unifyCons.toString()); + unifyCons = unifyCons.map(distributeInnerVars); + logFile.write(unifyCons.toString()); + TypeUnify unify = new TypeUnify(); + //Set> results = new HashSet<>(); Nach vorne gezogen + logFile.write("FC:\\" + finiteClosure.toString()+"\n"); + for(SourceFile sf : this.sourceFiles.values()) { + logFile.write(ASTTypePrinter.print(sf)); + } + logFile.flush(); + + Set methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist() + .stream().filter(z -> z.getType() instanceof TypePlaceholder) + .map(z -> ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))) + .reduce(new HashSet(), (a,b) -> { a.addAll(b); return a;}, (a,b) -> { a.addAll(b); return a;} ) ) + .reduce(new HashSet(), (a,b) -> { a.addAll(b); return a;} ); + + Set constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().stream().map(y -> y.getParameterList().getFormalparalist() + .stream().filter(z -> z.getType() instanceof TypePlaceholder) + .map(z -> ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))) + .reduce(new HashSet(), (a,b) -> { a.addAll(b); return a;}, (a,b) -> { a.addAll(b); return a;} ) ) + .reduce(new HashSet(), (a,b) -> { a.addAll(b); return a;} ); + + Set paraTypeVarNames = methodParaTypeVarNames; + paraTypeVarNames.addAll(constructorParaTypeVarNames); + + + Set returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder) + .map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get(); + + Set fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder) + .map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get(); + + returnTypeVarNames.addAll(fieldTypeVarNames); + + unifyCons = unifyCons.map(x -> { + //Hier muss ueberlegt werden, ob + //1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs + // mit disableWildcardtable() werden. + //2. alle Typvariablen mit Argument- oder Retuntyp-Variablen + //in Beziehung auch auf disableWildcardtable() gesetzt werden muessen + //PL 2018-04-23 + if ((x.getLhsType() instanceof PlaceholderType)) { + if (paraTypeVarNames.contains(x.getLhsType().getName())) { + ((PlaceholderType)x.getLhsType()).setVariance((byte)1); + ((PlaceholderType)x.getLhsType()).disableWildcardtable(); + } + if (returnTypeVarNames.contains(x.getLhsType().getName())) { + ((PlaceholderType)x.getLhsType()).setVariance((byte)-1); + ((PlaceholderType)x.getLhsType()).disableWildcardtable(); + } + } + if ((x.getRhsType() instanceof PlaceholderType)) { + if (paraTypeVarNames.contains(x.getRhsType().getName())) { + ((PlaceholderType)x.getRhsType()).setVariance((byte)1); + ((PlaceholderType)x.getRhsType()).disableWildcardtable(); + } + if (returnTypeVarNames.contains(x.getRhsType().getName())) { + ((PlaceholderType)x.getRhsType()).setVariance((byte)-1); + ((PlaceholderType)x.getRhsType()).disableWildcardtable(); + } + } + return x;//HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE JEWEILS ANDERE SEITE + }); + Set varianceTPHold; + Set varianceTPH = new HashSet<>(); + varianceTPH = varianceInheritanceConstraintSet(unifyCons); + + /* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt + do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen + //anderen Seite übertragen + varianceTPHold = new HashSet<>(varianceTPH); + varianceTPH = varianceInheritanceConstraintSet(unifyCons); + unifyCons.map( y -> { + if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { + if (((PlaceholderType)y.getLhsType()).getVariance() != 0 && ((PlaceholderType)y.getRhsType()).getVariance() == 0) { + ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType()).getVariance()); + } + if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { + ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType()).getVariance()); + } + } + return y; } ); } + while (!varianceTPHold.equals(varianceTPH)); + */ + + //Set> result = unify.unifySequential(xConsSet, finiteClosure, logFile, log); + //Set> result = unify.unify(xConsSet, finiteClosure); + List>> oderConstraints = unifyCons.getOderConstraints().stream().map(x -> { + Set> ret = new HashSet<>(); + for (Constraint y : x) { + ret.add(new HashSet<>(y)); + } + return ret; + }).collect(Collectors.toCollection(ArrayList::new)); + unify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons, urm); + } + catch (IOException e) { + System.err.println("kein LogFile"); + } + return urm; } diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java index d8588ae4..eb81e200 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java @@ -1878,13 +1878,13 @@ public class TypeUnifyTask extends RecursiveTask>> { allGen = false; break; } - if (thetaPrime.getName().equals("java.util.Vector") //Fuer Bug 127 - && thetaPrime instanceof ReferenceType - && ((ReferenceType)thetaPrime).getTypeParams().iterator().next().getName().equals("java.util.Vector")) + //if (thetaPrime.getName().equals("java.util.Vector") //Fuer Bug 127 + // && thetaPrime instanceof ReferenceType + // && ((ReferenceType)thetaPrime).getTypeParams().iterator().next() instanceof PlaceholderType) //.getName().equals("java.util.Vector")) // && ((ReferenceType)((ReferenceType)thetaPrime).getTypeParams().iterator().next()).getTypeParams().iterator().next().getName().equals("java.lang.Integer")) { - { - System.out.println(""); - } + // { + // System.out.println(""); + //} Set cs = fc.getAllTypesByName(thetaPrime.getName());//cs= [java.util.Vector, java.util.Vector>, ????java.util.Vector???] @@ -1979,7 +1979,7 @@ public class TypeUnifyTask extends RecursiveTask>> { if(allGen) { UnifyPair up = new UnifyPair(a, theta, PairOperator.EQUALSDOT, pair.getSubstitution(), pair); Iterator upit = up.getRhsType().getTypeParams().iterator(); - //TODO PL 2019-01-24: upit.next() ist nicht unbedingt ein PlaceholderType -> Visitor + //TODO PL 2019-01-24: upit.next() ist nicht unbedingt ein PlaceholderType -> Visitor erledigt while (upit.hasNext()) upit.next().accept(new distributeVariance(), a.getVariance());//((PlaceholderType)upit.next()).setVariance(a.getVariance()); resultPrime.add(up); } @@ -1987,7 +1987,7 @@ public class TypeUnifyTask extends RecursiveTask>> { UnifyPair up = new UnifyPair(a, theta.setTypeParams(new TypeParams(freshTphs.toArray(new UnifyType[0]))), PairOperator.EQUALSDOT, pair.getSubstitution(), pair); Iterator upit = up.getRhsType().getTypeParams().iterator(); distributeVariance dv = new distributeVariance(); - //TODO PL 2019-01-24: upit.next() ist nicht unbedingt ein PlaceholderType -> Visitor + //TODO PL 2019-01-24: upit.next() ist nicht unbedingt ein PlaceholderType -> Visitor erledigt while (upit.hasNext()) upit.next().accept(new distributeVariance(), a.getVariance()); //((PlaceholderType)upit.next()).setVariance(a.getVariance()); resultPrime.add(up); } diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListenerImpl.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListenerImpl.java index 16133a3f..ea34728b 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListenerImpl.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListenerImpl.java @@ -10,7 +10,7 @@ public class UnifyResultListenerImpl implements UnifyResultListener { List results = new ArrayList<>(); - public void onNewTypeResultFound(UnifyResultEvent evt) { + public synchronized void onNewTypeResultFound(UnifyResultEvent evt) { results.addAll(evt.getNewTypeResult()); } From 2eaebbf0f809efe29c5c702e6265a183986a992e Mon Sep 17 00:00:00 2001 From: Michael Uhl Date: Fri, 1 Feb 2019 22:56:30 +0100 Subject: [PATCH 12/19] FileWriter -> Writer. --- src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java | 6 +++++- .../dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java | 3 ++- .../java/de/dhbwstuttgart/typeinference/unify/RuleSet.java | 5 +++-- .../de/dhbwstuttgart/typeinference/unify/TypeUnify.java | 3 ++- .../dhbwstuttgart/typeinference/unify/TypeUnify2Task.java | 3 ++- .../de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java | 5 +++-- .../typeinference/unify/model/FiniteClosure.java | 5 +++-- 7 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java index 2c19d8b3..446cd514 100644 --- a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -41,12 +41,15 @@ import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; import org.antlr.v4.parse.ANTLRParser.throwsSpec_return; +import org.apache.commons.io.output.NullOutputStream; public class JavaTXCompiler { @@ -286,7 +289,8 @@ public class JavaTXCompiler { Set> results = new HashSet<>(); UnifyResultModel urm = new UnifyResultModel(); try { - FileWriter logFile = new FileWriter(new File(System.getProperty("user.dir")+"/src/test/java/logFiles/"+"log_"+sourceFiles.keySet().iterator().next().getName())); + Writer logFile = new OutputStreamWriter(new NullOutputStream()); + //new FileWriter(new File("log_"+sourceFiles.keySet().iterator().next().getName())); IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses,logFile); System.out.println(finiteClosure); diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index f3fbdd63..a764db6e 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -1,6 +1,7 @@ package de.dhbwstuttgart.syntaxtree.factory; import java.io.FileWriter; +import java.io.Writer; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -30,7 +31,7 @@ public class UnifyTypeFactory { private static ArrayList PLACEHOLDERS = new ArrayList<>(); - public static FiniteClosure generateFC(List fromClasses, FileWriter logFile) throws ClassNotFoundException { + public static FiniteClosure generateFC(List fromClasses, Writer logFile) throws ClassNotFoundException { /* Die transitive Hülle muss funktionieren. Man darf schreiben List extends AL diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java index a8c0675d..e333bdfe 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java @@ -28,6 +28,7 @@ import de.dhbwstuttgart.typeinference.unify.distributeVariance; import java.io.FileWriter; import java.io.IOException; +import java.io.Writer; /** * Implementation of the type inference rules. @@ -36,13 +37,13 @@ import java.io.IOException; */ public class RuleSet implements IRuleSet{ - FileWriter logFile; + Writer logFile; public RuleSet() { super(); } - RuleSet(FileWriter logFile) { + RuleSet(Writer logFile) { this.logFile = logFile; } diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java index d1fc2afe..6d58b959 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java @@ -1,6 +1,7 @@ package de.dhbwstuttgart.typeinference.unify; import java.io.FileWriter; +import java.io.Writer; import java.util.List; import java.util.Set; import java.util.concurrent.ForkJoinPool; @@ -21,7 +22,7 @@ public class TypeUnify { return res; } - public UnifyResultModel unifyAsync(Set undConstrains, List>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet cons, UnifyResultModel ret) { + public UnifyResultModel unifyAsync(Set undConstrains, List>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, ConstraintSet cons, UnifyResultModel ret) { TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, cons); ForkJoinPool pool = new ForkJoinPool(); pool.invoke(unifyTask); diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java index 6916f6dc..ac6f04bb 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java @@ -1,6 +1,7 @@ package de.dhbwstuttgart.typeinference.unify; import java.io.FileWriter; +import java.io.Writer; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -15,7 +16,7 @@ public class TypeUnify2Task extends TypeUnifyTask { Set> setToFlatten; - public TypeUnify2Task(Set> setToFlatten, Set eq, List>> oderConstraints, IFiniteClosure fc, boolean parallel, FileWriter logFile, Boolean log, int rekTiefe, UnifyResultModel urm, ConstraintSet cons) { + public TypeUnify2Task(Set> setToFlatten, Set eq, List>> oderConstraints, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm, ConstraintSet cons) { super(eq, oderConstraints, fc, parallel, logFile, log, rekTiefe, urm, cons); this.setToFlatten = setToFlatten; } diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java index eb81e200..43142773 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java @@ -44,6 +44,7 @@ import de.dhbwstuttgart.typeinference.unify.model.Pair; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.io.Writer; import com.google.common.collect.Ordering; @@ -71,7 +72,7 @@ public class TypeUnifyTask extends RecursiveTask>> { Integer MaxNoOfThreads = 8; public static final String rootDirectory = System.getProperty("user.dir")+"/test/logFiles/"; - FileWriter logFile; + Writer logFile; /** * The implementation of setOps that will be used during the unification @@ -128,7 +129,7 @@ public class TypeUnifyTask extends RecursiveTask>> { } */ - public TypeUnifyTask(Set eq, List>> oderConstraints, IFiniteClosure fc, boolean parallel, FileWriter logFile, Boolean log, int rekTiefe, UnifyResultModel urm, ConstraintSet cons2) { + public TypeUnifyTask(Set eq, List>> oderConstraints, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm, ConstraintSet cons2) { synchronized (this) { this.eq = eq; //this.oderConstraints = oderConstraints.stream().map(x -> x.stream().map(y -> new HashSet<>(y)).collect(Collectors.toSet(HashSet::new))).collect(Collectors.toList(ArrayList::new)); diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index c52f47a7..29a0e198 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -2,6 +2,7 @@ package de.dhbwstuttgart.typeinference.unify.model; import java.io.FileWriter; import java.io.IOException; +import java.io.Writer; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -32,7 +33,7 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; public class FiniteClosure //extends Ordering //entfernt PL 2018-12-11 implements IFiniteClosure { - FileWriter logFile; + Writer logFile; static Boolean log = false; public void setLogTrue() { log = true; @@ -66,7 +67,7 @@ implements IFiniteClosure { /** * Creates a new instance using the inheritance tree defined in the pairs. */ - public FiniteClosure(Set pairs, FileWriter logFile) { + public FiniteClosure(Set pairs, Writer logFile) { this.logFile = logFile; this.pairs = new HashSet<>(pairs); inheritanceGraph = new HashMap>(); From d2581b02ab6f0c2979633f3b8a1f9ad7baf29f0b Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Thu, 14 Feb 2019 11:37:15 +0100 Subject: [PATCH 13/19] modified: src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java Bug in generate BC fuer if(Boolean) gefixt modified: src/main/java/de/dhbwstuttgart/bytecode/signature/Signature.java new file: src/main/java/de/dhbwstuttgart/bytecode/utilities/ConstraintsFinder.java Fasst alle Constraints mit der gleichen Linke-Seite in einer Liste zusammen new file: src/main/java/de/dhbwstuttgart/bytecode/utilities/NameReplacer.java Ersetzt die gleiche Type Variables durch einen neuen eindeutigen Namen modified: src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java Algorithmus angepasst modified: src/test/java/bytecode/FieldTphMMethTest.java Test funktioniert new file: src/test/java/bytecode/InfTest.java Infimum Test funktioniert new file: src/test/java/bytecode/simplifyalgo/FinderTest.java Tests fuer die HilfsMethoden --- .../bytecode/BytecodeGenMethod.java | 150 ++++++++++-------- .../bytecode/signature/Signature.java | 2 +- .../bytecode/utilities/ConstraintsFinder.java | 48 ++++++ .../bytecode/utilities/NameReplacer.java | 44 +++++ .../bytecode/utilities/Simplify.java | 119 +++++++++----- src/test/java/bytecode/FieldTphMMethTest.java | 29 +++- src/test/java/bytecode/InfTest.java | 37 +++++ .../bytecode/simplifyalgo/FinderTest.java | 64 ++++++++ .../bytecode/javFiles/FieldTphMMeth.jav | 9 +- src/test/resources/bytecode/javFiles/Inf.jav | 14 ++ 10 files changed, 398 insertions(+), 118 deletions(-) create mode 100644 src/main/java/de/dhbwstuttgart/bytecode/utilities/ConstraintsFinder.java create mode 100644 src/main/java/de/dhbwstuttgart/bytecode/utilities/NameReplacer.java create mode 100644 src/test/java/bytecode/InfTest.java create mode 100644 src/test/java/bytecode/simplifyalgo/FinderTest.java create mode 100644 src/test/resources/bytecode/javFiles/Inf.jav diff --git a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index ff2c49a3..ef9b9946 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -744,6 +744,13 @@ public class BytecodeGenMethod implements StatementVisitor { statement = new IfStatement(ifStmt.expr, ifStmt.then_block, ifStmt.else_block); isBinaryExp = statement.isExprBinary(); ifStmt.expr.accept(this); + if(!(ifStmt.expr instanceof BinaryExpr)) { + doUnboxing(getResolvedType(ifStmt.expr.getType())); + Label branchLabel = new Label(); + Label endLabel = new Label(); + mv.visitJumpInsn(Opcodes.IFEQ, branchLabel); + statement.genBCForRelOp(mv, branchLabel, endLabel, this); + } statement = null; } @@ -758,86 +765,90 @@ public class BytecodeGenMethod implements StatementVisitor { System.out.println("In MethodCall = " + methodCall.name); String receiverName = getResolvedType(methodCall.receiver.getType()); System.out.println("Methods of " + receiverName + " "); - ClassLoader cLoader = ClassLoader.getSystemClassLoader(); - // This will be used if the class is not standard class (not in API) - ClassLoader cLoader2; java.lang.reflect.Method methodRefl = null; String clazz = receiverName.replace("/", "."); - String methCallType = resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor()); - String[] typesOfParams = getTypes(methodCall.arglist.getArguments()); - try { - if(receiverName.contains("<")) { - clazz = clazz.substring(0, receiverName.indexOf("<")); - } + if(!receiverName.equals(className)) { + ClassLoader cLoader = ClassLoader.getSystemClassLoader(); + // This will be used if the class is not standard class (not in API) + ClassLoader cLoader2; - java.lang.reflect.Method[] methods = cLoader.loadClass(clazz).getMethods(); - System.out.println("Methods of " + receiverName + " "); - methodRefl = getMethod(methodCall.name,methodCall.arglist.getArguments().size(),methods); - - } catch (Exception e) { -// try { -// cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)}); -// java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods(); -// System.out.println("Methods of " + receiverName + " "); -// for(int i = 0; i allConstaints; + + public ConstraintsFinder(List allConstaints) { + super(); + this.allConstaints = allConstaints; + } + + public List> findConstraints() { + List> result = new ArrayList<>(); + + List visitedCons = new ArrayList<>(); + for(TPHConstraint c : allConstaints) { + // get constraints with the same left side + List cons = getConstraints(c,visitedCons); + if(cons.size()>1) + result.add(cons); + } + + return result; + } + + private List getConstraints(TPHConstraint c, List visitedCons) { + List res = new ArrayList<>(); + for(TPHConstraint cons : allConstaints) { + if(!isVisited(cons,visitedCons) && cons.getLeft().equals(c.getLeft())) { + res.add(cons); + visitedCons.add(cons); + } + } + return res; + } + + private boolean isVisited(TPHConstraint cons, List visitedCons) { + for(TPHConstraint c : visitedCons) { + if(c.getLeft().equals(cons.getLeft()) && c.getRight().equals(cons.getRight())) + return true; + } + return false; + } +} diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/NameReplacer.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/NameReplacer.java new file mode 100644 index 00000000..8b906eee --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/NameReplacer.java @@ -0,0 +1,44 @@ +package de.dhbwstuttgart.bytecode.utilities; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; +import de.dhbwstuttgart.syntaxtree.factory.NameGenerator; + +public class NameReplacer { + private List constraints; + private List allConstraints; + private List tphs; + + public NameReplacer(List constraints, List allConstraints,List tphs) { + super(); + this.constraints = constraints; + this.allConstraints = allConstraints; + this.tphs = tphs; + } + + public Map> replaceNames() { + String newName = NameGenerator.makeNewName(); + ArrayList names = new ArrayList<>(); + for(TPHConstraint cons : constraints) { + names.add(cons.getRight()); + cons.setRight(newName); + } + + for(TPHConstraint cons : allConstraints) { + if(names.contains(cons.getLeft())) + cons.setLeft(newName); + if(names.contains(cons.getRight())) + cons.setRight(newName); + } + tphs.removeAll(names); + tphs.add(newName); + + HashMap> res = new HashMap<>(); + res.put(newName, names); + return res; + } +} diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java index 2e3ce775..83eb7cc7 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java @@ -4,6 +4,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; +import java.util.List; +import java.util.Map; import org.objectweb.asm.Type; @@ -177,7 +179,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); + if(!cons.getRight().equals(Type.getInternalName(Object.class))) + result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS), null); } return result; @@ -198,50 +201,79 @@ public class Simplify { break; } } + + ConstraintsFinder finder = new ConstraintsFinder(allCons); + List> foundCons = finder.findConstraints(); + + ArrayList eqCons = new ArrayList<>(); + + for(List list : foundCons) { + NameReplacer replacer = new NameReplacer(list,allCons,methodTphs); + Map> replRes = replacer.replaceNames(); + + String key = replRes.keySet().iterator().next(); + for(String val : replRes.values().iterator().next()) { + EqualConstraint ec = new EqualConstraint(val, key, Relation.EQUAL); + eqCons.add(ec); + } + + updateEqualCons(replRes,eqCons); + + TPHConstraint c = list.get(0); + allCons.removeAll(list); + allCons.add(c); + } + // 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 subAndSuper = new HashMap<>(); +// ArrayList eqCons = new ArrayList<>(); +// for(TPHConstraint c : allCons) { +// if(subAndSuper.containsKey(c.getLeft())) { +// LinkedList all = new LinkedList<>(); +// all.add(c.getLeft()); +// String sup =c.getRight(); +// all.add(sup); +// HashMap ss = new HashMap<>(); +// for(TPHConstraint constr : allCons) { +// ss.put(constr.getLeft(), constr.getRight()); +// } +// while(ss.containsKey(sup)) { +// sup = ss.get(sup); +// all.add(sup); +// } +// if(!containTPH(methodTphs, all.getLast())) +// continue; +// } +// if(subAndSuper.containsKey(c.getLeft())) { +// System.out.println(c.getLeft()); +// String r = c.getRight(); +// String r2 = subAndSuper.get(c.getLeft()); +// EqualConstraint eq = new EqualConstraint(r2, r, Relation.EQUAL); +// eqCons.add(eq); +// substituteInMap(subAndSuper,eqCons,allCons,r,r2); +// } +// subAndSuper.put(c.getLeft(), c.getRight()); +// } +// +// System.out.println("SAME LEFT SIDE: "); +// subAndSuper.forEach((c,hs)->{ +// if(c!=null) { +// System.out.print(c+ " -> " + hs); +// +// } +// +// +// System.out.println(); +// }); +// System.out.println("----------------"); HashMap subAndSuper = new HashMap<>(); - ArrayList eqCons = new ArrayList<>(); + for(TPHConstraint c : allCons) { - if(subAndSuper.containsKey(c.getLeft())) { - LinkedList all = new LinkedList<>(); - all.add(c.getLeft()); - String sup =c.getRight(); - all.add(sup); - HashMap ss = new HashMap<>(); - for(TPHConstraint constr : allCons) { - ss.put(constr.getLeft(), constr.getRight()); - } - while(ss.containsKey(sup)) { - sup = ss.get(sup); - all.add(sup); - } - if(!containTPH(methodTphs, all.getLast())) - continue; - } - if(subAndSuper.containsKey(c.getLeft())) { - System.out.println(c.getLeft()); - String r = c.getRight(); - String r2 = subAndSuper.get(c.getLeft()); - EqualConstraint eq = new EqualConstraint(r2, r, Relation.EQUAL); - eqCons.add(eq); - substituteInMap(subAndSuper,eqCons,allCons,r,r2); - } subAndSuper.put(c.getLeft(), c.getRight()); } - System.out.println("SAME LEFT SIDE: "); - subAndSuper.forEach((c,hs)->{ - if(c!=null) { - System.out.print(c+ " -> " + hs); - - } - - - System.out.println(); - }); - System.out.println("----------------"); int numOfVisitedPairs = 0; for(String sub : subAndSuper.keySet()) { if(isTPHInConstraint(result,sub)) @@ -348,6 +380,19 @@ public class Simplify { } + private static void updateEqualCons(Map> replRes, ArrayList eqCons) { + List oldNames = replRes.values().iterator().next(); + String newName = replRes.keySet().iterator().next(); + for(TPHConstraint c : eqCons) { +// if(oldNames.contains(c.getLeft())) +// c.setLeft(newName); + if(oldNames.contains(c.getRight())) + c.setRight(newName); + } + + } + + public static HashMap> simplifyConstraintsClass(TPHExtractor tphExtractor, ArrayList tphsClass) { // all constraints that will be simplified ArrayList allCons = tphExtractor.allCons; diff --git a/src/test/java/bytecode/FieldTphMMethTest.java b/src/test/java/bytecode/FieldTphMMethTest.java index 58a9647a..f21adefe 100644 --- a/src/test/java/bytecode/FieldTphMMethTest.java +++ b/src/test/java/bytecode/FieldTphMMethTest.java @@ -33,20 +33,33 @@ public class FieldTphMMethTest { pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"; loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); classToTest = loader.loadClass("FieldTphMMeth"); + instanceOfClass = classToTest.getConstructor(Object.class,Object.class,Boolean.class).newInstance("C",42,true); + instanceOfClass2 = classToTest.getConstructor(Object.class,Object.class,Boolean.class).newInstance("C",42,false); } @Test - public void test() throws Exception { - instanceOfClass = classToTest.getConstructor(Object.class).newInstance("C",42,true); - instanceOfClass2 = classToTest.getConstructor(Object.class).newInstance("C",42,false); + public void testM() throws Exception { + + Method m = classToTest.getDeclaredMethod("m", Object.class,Object.class,Boolean.class); + Object result = m.invoke(instanceOfClass, "C",42,false); + + assertEquals(42,result); + } + + @Test + public void testWithTrue() throws Exception { + Field a = classToTest.getDeclaredField("a"); + a.setAccessible(true); + + assertEquals("C", a.get(instanceOfClass)); + + } + + @Test + public void testWithFalse() throws Exception { Field a = classToTest.getDeclaredField("a"); a.setAccessible(true); - Method m = classToTest.getDeclaredMethod("m", Object.class); - Object result = m.invoke(instanceOfClass, 42); - - assertEquals(42,result); - assertEquals("C", a.get(instanceOfClass)); assertEquals(42, a.get(instanceOfClass2)); } diff --git a/src/test/java/bytecode/InfTest.java b/src/test/java/bytecode/InfTest.java new file mode 100644 index 00000000..75608bfe --- /dev/null +++ b/src/test/java/bytecode/InfTest.java @@ -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 InfTest { + + 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/Inf.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("Inf"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + } + +} diff --git a/src/test/java/bytecode/simplifyalgo/FinderTest.java b/src/test/java/bytecode/simplifyalgo/FinderTest.java new file mode 100644 index 00000000..edf43605 --- /dev/null +++ b/src/test/java/bytecode/simplifyalgo/FinderTest.java @@ -0,0 +1,64 @@ +package bytecode.simplifyalgo; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; + +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.ConstraintsFinder; +import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH; +import de.dhbwstuttgart.bytecode.utilities.Simplify; +import de.dhbwstuttgart.typedeployment.TypeInsertPlacer; + +/** + * + * @author Fayez Abu Alia + * + */ +public class FinderTest { + + @Test + public void testM1() { + List allCons = new ArrayList<>(); + // L < M + TPHConstraint c1 = new ExtendsConstraint("L", "M", Relation.EXTENDS); + // L < N + TPHConstraint c2 = new ExtendsConstraint("L", "N", Relation.EXTENDS); + // M < O + TPHConstraint c3 = new ExtendsConstraint("M", "O", Relation.EXTENDS); + // M < P + TPHConstraint c4 = new ExtendsConstraint("M", "P", Relation.EXTENDS); + + allCons.add(c1); + allCons.add(c2); + allCons.add(c3); + allCons.add(c4); + List> res = new ArrayList<>(); + List l1 = new ArrayList<>(); + List l2 = new ArrayList<>(); + + l1.add(c1); + l1.add(c2); + + l2.add(c3); + l2.add(c4); + + res.add(l1); + res.add(l2); + + ConstraintsFinder finder = new ConstraintsFinder(allCons); + + assertEquals(finder.findConstraints(), res); + } + +} diff --git a/src/test/resources/bytecode/javFiles/FieldTphMMeth.jav b/src/test/resources/bytecode/javFiles/FieldTphMMeth.jav index abc10a46..ad97edc4 100644 --- a/src/test/resources/bytecode/javFiles/FieldTphMMeth.jav +++ b/src/test/resources/bytecode/javFiles/FieldTphMMeth.jav @@ -1,14 +1,17 @@ +import java.lang.Boolean; + public class FieldTphMMeth { a; - public FieldTphConsMeth(c,d,e) { + + public FieldTphMMeth(c,d,e) { a = m(c,d,e); } m(b,d,e) { if(e) { - return b; + return m3(b); } else{ - m2(d); + return m3(d); } } diff --git a/src/test/resources/bytecode/javFiles/Inf.jav b/src/test/resources/bytecode/javFiles/Inf.jav new file mode 100644 index 00000000..79b9dca1 --- /dev/null +++ b/src/test/resources/bytecode/javFiles/Inf.jav @@ -0,0 +1,14 @@ +public class Inf { + m(x,y,a){ + var z; + var v; + var w; + var b; + y=x; + z=x; + v=y; + w=y; + y=a; + b=a; + } +} \ No newline at end of file From d010c843df9d265819411c21cee0487e6463ae86 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 20 Feb 2019 12:15:55 +0100 Subject: [PATCH 14/19] Bug in MatrixTest gefixt. Die richtige Descriptor von MethodCalls wird erzeugt --- .../java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java | 7 ++++--- .../de/dhbwstuttgart/bytecode/utilities/Simplify.java | 8 ++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index ef9b9946..dd3d27ed 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -767,7 +767,7 @@ public class BytecodeGenMethod implements StatementVisitor { System.out.println("Methods of " + receiverName + " "); java.lang.reflect.Method methodRefl = null; String clazz = receiverName.replace("/", "."); - if(!receiverName.equals(className)) { +// if(!receiverName.equals(className)) { ClassLoader cLoader = ClassLoader.getSystemClassLoader(); // This will be used if the class is not standard class (not in API) ClassLoader cLoader2; @@ -847,7 +847,7 @@ public class BytecodeGenMethod implements StatementVisitor { //do nothing } } - } +// } methodCall.receiver.accept(this); @@ -861,6 +861,7 @@ public class BytecodeGenMethod implements StatementVisitor { mDesc = method.accept(new DescriptorToString(resultSet)); methodCall.arglist.accept(this); } else { + System.out.println(methodCall.name + " -> Refl != null"); receiverRefl = methodRefl.getAnnotatedReceiverType().getType().toString(); for(Parameter p:methodRefl.getParameters()) { System.out.println(p.getName() + " und is Primitive = " + p.getType().isPrimitive()); @@ -876,7 +877,7 @@ public class BytecodeGenMethod implements StatementVisitor { } } - System.out.println("Methodcall Desc : " + mDesc); + System.out.println("Methodcall ("+ methodCall.name +") Desc : " + mDesc); // methodCall.arglist.accept(this); diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java index 83eb7cc7..e1528254 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java @@ -201,16 +201,20 @@ public class Simplify { break; } } - + // finder looks for constraints that have the same left hand side + // and put them in a list ConstraintsFinder finder = new ConstraintsFinder(allCons); List> foundCons = finder.findConstraints(); ArrayList eqCons = new ArrayList<>(); for(List 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); + // new name -> [all old names] Map> replRes = replacer.replaceNames(); - + // create an equal constraint for each value in repres String key = replRes.keySet().iterator().next(); for(String val : replRes.values().iterator().next()) { EqualConstraint ec = new EqualConstraint(val, key, Relation.EQUAL); From 8e4b39b05e87650d6329badbfe4bb1b3f3046d8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Wed, 20 Feb 2019 16:03:56 +0100 Subject: [PATCH 15/19] modified: ../../test/resources/bytecode/javFiles/Inf.jav --- src/test/resources/bytecode/javFiles/Inf.jav | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test/resources/bytecode/javFiles/Inf.jav b/src/test/resources/bytecode/javFiles/Inf.jav index 79b9dca1..3c785a6e 100644 --- a/src/test/resources/bytecode/javFiles/Inf.jav +++ b/src/test/resources/bytecode/javFiles/Inf.jav @@ -11,4 +11,9 @@ public class Inf { y=a; b=a; } -} \ No newline at end of file +} +// v w +// \ / +// z y b +// \ / \ / +// x a \ No newline at end of file From 3e186334a2077e37de084c36e4142b2b60bed43b Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Thu, 21 Feb 2019 13:34:36 +0100 Subject: [PATCH 16/19] Simpify Algo korrigiert so dass die lokalen Variablen der Methode beruecksichtigt werden --- .../dhbwstuttgart/bytecode/TPHExtractor.java | 68 +- .../bytecode/utilities/ConstraintsFinder.java | 11 +- .../bytecode/utilities/MethodAndTPH.java | 7 + .../bytecode/utilities/NameReplacer.java | 7 +- .../bytecode/utilities/Simplify.java | 1074 +++++++++-------- src/test/java/bytecode/KompTphTest.java | 37 + .../resources/bytecode/javFiles/KompTph.jav | 13 + 7 files changed, 700 insertions(+), 517 deletions(-) create mode 100644 src/test/java/bytecode/KompTphTest.java create mode 100644 src/test/resources/bytecode/javFiles/KompTph.jav diff --git a/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java b/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java index 0135631e..c100eb4a 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java @@ -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; @@ -21,36 +26,42 @@ import de.dhbwstuttgart.typeinference.result.ResultSet; * @author Fayez Abu Alia * */ -public class TPHExtractor extends AbstractASTWalker{ +public class TPHExtractor extends AbstractASTWalker { // Alle TPHs der Felder werden iKopf der Klasse definiert // alle TPHs der Klasse: (TPH, is in Method?) - final HashMap allTPHS = new HashMap<>(); + final HashMap allTPHS = new HashMap<>(); MethodAndTPH methodAndTph; + Boolean inMethod = false; + boolean inLocalOrParam = false; + public final ArrayList ListOfMethodsAndTph = new ArrayList<>(); final ArrayList allPairs = new ArrayList<>(); public final ArrayList 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) { + if (resultSet.resolveType(tph).resolvedType instanceof TypePlaceholder) { TypePlaceholder resolvedTPH = (TypePlaceholder) resultSet.resolveType(tph).resolvedType; - if(inMethod) + 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) + if (inLocalOrParam) + methodAndTph.getLocalTphs().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); @@ -59,14 +70,16 @@ public class TPHExtractor extends AbstractASTWalker{ }); } } + private boolean contains(ArrayList pairs, GenericInsertPair genPair) { - for(int i=0; i allConstaints; @@ -18,10 +19,12 @@ public class ConstraintsFinder { List visitedCons = new ArrayList<>(); for(TPHConstraint c : allConstaints) { - // get constraints with the same left side - List cons = getConstraints(c,visitedCons); - if(cons.size()>1) - result.add(cons); + if(c.getRel() == Relation.EXTENDS) { + // get constraints with the same left side + List cons = getConstraints(c,visitedCons); + if(cons.size()>1) + result.add(cons); + } } return result; diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodAndTPH.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodAndTPH.java index 7175f108..e21f974c 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodAndTPH.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodAndTPH.java @@ -10,6 +10,8 @@ public class MethodAndTPH { private String name; private final ArrayList tphs = new ArrayList<>(); private final ArrayList pairs = new ArrayList<>(); + // tphs of local variables and parameters + private final ArrayList localTphs = new ArrayList<>(); public MethodAndTPH(String name) { this.name = name; @@ -26,4 +28,9 @@ public class MethodAndTPH { public String getName() { return name; } + + public ArrayList getLocalTphs() { + return localTphs; + } + } diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/NameReplacer.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/NameReplacer.java index 8b906eee..bc3c1b98 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/NameReplacer.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/NameReplacer.java @@ -12,12 +12,14 @@ public class NameReplacer { private List constraints; private List allConstraints; private List tphs; + private List localTphs; - public NameReplacer(List constraints, List allConstraints,List tphs) { + public NameReplacer(List constraints, List allConstraints,List tphs, ArrayList localTphs) { super(); this.constraints = constraints; this.allConstraints = allConstraints; this.tphs = tphs; + this.localTphs = localTphs; } public Map> 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> res = new HashMap<>(); res.put(newName, names); diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java index e1528254..89b55efb 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java @@ -17,125 +17,145 @@ import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; public class Simplify { - - public static HashMap> simplifyConstraints(String name, TPHExtractor tphExtractor, ArrayList tphsClass) { + + public static HashMap> simplifyConstraints(String name, TPHExtractor tphExtractor, + ArrayList tphsClass) { // 1. check if there are any simple cycles like L 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 .. - // a) yes => put all such TPhs in a map and define "key-Cons" - // -- key-Cons = TPH < Object -- - // put this Constraint and the - // b) no + // 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 .. + // a) yes => put all such TPhs in a map and define "key-Cons" + // -- key-Cons = TPH < Object -- + // put this Constraint and the + // b) no // 3. is - + // all constraints that will be simplified - ArrayList allCons = tphExtractor.allCons; +// ArrayList allCons = tphExtractor.allCons; + ArrayList allCons = new ArrayList<>(); + + for(TPHConstraint c : tphExtractor.allCons) { + TPHConstraint nc = new TPHConstraint(c.getLeft(), c.getRight(), c.getRel()); + allCons.add(nc); + } ArrayList consToRemove = new ArrayList<>(); - + + // get all tph of the method + ArrayList methodTphs = new ArrayList<>(); + ArrayList 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) { - + for (TPHConstraint c : allCons) { + String left = c.getLeft(); String right = c.getRight(); - if(c.getRel() == Relation.EXTENDS) { - TPHConstraint revCon = getReverseConstraint(allCons,left,right); - if(revCon != null) { + if (c.getRel() == Relation.EXTENDS) { + TPHConstraint revCon = getReverseConstraint(allCons, left, right); + if (revCon != null) { revCon.setRel(Relation.EQUAL); - // the reverse constraint is removed because - // otherwise there is the same constraint twice - // (e.g. A A=B and B=A) + // the reverse constraint is removed because + // otherwise there is the same constraint twice + // (e.g. A A=B and B=A) consToRemove.add(revCon); c.setRel(Relation.EQUAL); - substituteTPH(allCons,left, right); + substituteTPH(allCons, left, right); } } } - + System.out.println(); System.out.println("NEW ALL CONST: " + allCons.size()); - allCons.forEach(c->System.out.println(c.toString())); + allCons.forEach(c -> System.out.println(c.toString())); System.out.println("----------------"); allCons.removeAll(consToRemove); consToRemove = new ArrayList<>(); - + int size = allCons.size(); - + System.out.println("AFTER DELETE ALL CONST: " + allCons.size()); - allCons.forEach(c->System.out.println(c.toString())); + allCons.forEach(c -> System.out.println(c.toString())); System.out.println("----------------"); HashMap> result = new HashMap<>(); - + // check if there is any long cycle (e.g. A 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 constraints = new ArrayList<>(size); int visited = 0; - + // contains all constraints - HashMap ss1 = new HashMap<>(); - - for(TPHConstraint constr : allCons) { + HashMap ss1 = new HashMap<>(); + + for (TPHConstraint constr : allCons) { ss1.put(constr.getLeft(), constr.getRight()); } - - for(TPHConstraint c : allCons) { - - if(visited >= size) + + for (TPHConstraint c : allCons) { + + if (visited >= size) break; // Only extends-constraints will be checked - if(c.getRel() == Relation.EXTENDS) { + 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)) { + while (ss1.containsKey(right)) { ++visited; String oldRight = right; right = ss1.get(right); - + TPHConstraint toAdd = getConstraint(oldRight, right, allCons); - - if(toAdd != null) + + if (toAdd != null) constraints.add(toAdd); - - if(left.equals(right)) { + + if (left.equals(right)) { isCycle = true; break; } - + allTypes.add(right); } - - if(isCycle) { + + 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); - + substituteAllTPH(allCons, constraints, left); + HashSet eq = new HashSet<>(); // put all equal types in a set - for(String t:allTypes) { + for (String t : allTypes) { 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,93 +163,100 @@ public class Simplify { 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) { - if(c.getRel()==Relation.EQUAL) { - if(!isTPHInResEqual(result, c.getLeft())) { - HashSet equalTPHs = getEqualsTPHs(result, c); - TPHConstraint constraint = getKeyConstraint(result,c); - equalTPHs.add(c.getLeft()); - equalTPHs.add(c.getRight()); - result.put(constraint, equalTPHs); + + for (TPHConstraint ec : allCons) { + + if(ec.getRel() == Relation.EQUAL) { + if(!localTphs.contains(ec.getRight())) { + localTphs.add(ec.getRight()); } - consToRemove.add(c); - size--; + 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 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)->{ + result.forEach((c, hs) -> { System.out.print(c.toString() + " -> "); - hs.forEach(s->{ + hs.forEach(s -> { System.out.print(s + ", "); }); 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) { + + if (!allCons.isEmpty() && allCons.size() < 2) { TPHConstraint cons = allCons.get(0); - if(!result.containsKey(cons)) { + 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); + if (!cons.getRight().equals(Type.getInternalName(Object.class))) + result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class), + Relation.EXTENDS), null); } - + return result; } - + 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) { - if(c.getRight().equals(Type.getInternalName(Object.class))) + for (TPHConstraint c : allCons) { + if (c.getRight().equals(Type.getInternalName(Object.class))) size--; } - // get all tph of the method - ArrayList 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); List> foundCons = finder.findConstraints(); - + ArrayList eqCons = new ArrayList<>(); - - for(List list : foundCons) { + + for (List 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> replRes = replacer.replaceNames(); // create an equal constraint for each value in repres String key = replRes.keySet().iterator().next(); - for(String val : replRes.values().iterator().next()) { + for (String val : replRes.values().iterator().next()) { EqualConstraint ec = new EqualConstraint(val, key, Relation.EQUAL); eqCons.add(ec); } - - updateEqualCons(replRes,eqCons); - + for (TPHConstraint c : allCons) { + if (c.getRel() == Relation.EQUAL && key.equals(c.getRight())) { + eqCons.add(c); + } + } + updateEqualCons(replRes, eqCons); + TPHConstraint c = list.get(0); allCons.removeAll(list); allCons.add(c); } - + // check if there are multiple constraint with the same left side. - // if yes => check if the super type in the method, if not + // if yes => check if the super type in the method, if not // then ignore it. // HashMap subAndSuper = new HashMap<>(); // ArrayList eqCons = new ArrayList<>(); @@ -273,246 +300,123 @@ public class Simplify { // }); // System.out.println("----------------"); HashMap subAndSuper = new HashMap<>(); - - for(TPHConstraint c : allCons) { - subAndSuper.put(c.getLeft(), c.getRight()); + + 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)) + for (String sub : subAndSuper.keySet()) { + if (isTPHInConstraint(result, sub)) continue; - - if(!containTPH(methodTphs,sub)) + + if (!containTPH(methodTphs, sub)) continue; - - if(numOfVisitedPairs>=size) + + if (numOfVisitedPairs >= size) break; LinkedList tphInRel = new LinkedList<>(); tphInRel.add(sub); String superT = subAndSuper.get(sub); tphInRel.add(superT); - + numOfVisitedPairs++; - while(subAndSuper.containsKey(superT)) { + while (!localTphs.contains(superT) && subAndSuper.containsKey(superT)) { superT = subAndSuper.get(superT); - if(tphInRel.contains(superT)) { + if (tphInRel.contains(superT)) { break; } tphInRel.add(superT); numOfVisitedPairs++; } - + // Subtype String subTphRes = tphInRel.getFirst(); // Die größte Supertype String superTphRes = tphInRel.getLast(); - + // if there is any constraint X < subTph, then // add X at the beginning of the list. - while(subAndSuper.containsValue(subTphRes)) { - for(String tph : subAndSuper.keySet()) { - if(containTPH(methodTphs,tph) && subAndSuper.get(tph).equals(subTphRes)) { + while (!localTphs.contains(subTphRes) && subAndSuper.containsValue(subTphRes)) { + for (String tph : subAndSuper.keySet()) { + if (containTPH(methodTphs, tph) && subAndSuper.get(tph).equals(subTphRes)) { subTphRes = tph; break; } } - if(subTphRes.equals(tphInRel.getFirst())) { + if (subTphRes.equals(tphInRel.getFirst())) { break; } - - if(isTPHInConstraint(result, subTphRes)) + + if (isTPHInConstraint(result, subTphRes)) break; - + tphInRel.addFirst(subTphRes); numOfVisitedPairs++; } - + 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; - while(!containTPH(methodTphs,superTphRes) && (tphInRel.size()-i) >0) { - superTphRes = tphInRel.get(tphInRel.size()-i); + while (!containTPH(methodTphs, superTphRes) && (tphInRel.size() - i) > 0) { + superTphRes = tphInRel.get(tphInRel.size() - i); i++; } - - if(!containTPH(methodTphs, superTphRes)) { - HashSet equals = getEqualsTphsFromEqualCons(eqCons,superTphRes); - if(classTPHSContainsTPH(tphsClass,superTphRes)) { + + if (!containTPH(methodTphs, superTphRes)) { + HashSet equals = getEqualsTphsFromEqualCons(eqCons, superTphRes); + 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 { - HashSet equals = getEqualsTphsFromEqualCons(eqCons,subTphRes); + HashSet equals = getEqualsTphsFromEqualCons(eqCons, subTphRes); result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals); - if(!isTPHInConstraint(result, superTphRes) && !isTphInEqualSet(result,superTphRes)) { - HashSet equals2 = getEqualsTphsFromEqualCons(eqCons,superTphRes); - result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), equals2); + if (!isTPHInConstraint(result, superTphRes) && !isTphInEqualSet(result, superTphRes)) { + HashSet equals2 = getEqualsTphsFromEqualCons(eqCons, superTphRes); + result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), + equals2); } } } - - for(String tph : methodTphs) { - if(!isTPHInConstraint(result, tph) && !isTphInEqualSet(result,tph)) { - HashSet equals = getEqualsTphsFromEqualCons(eqCons,tph); + +// for(String tph : methodTphs) { + for (String tph : localTphs) { + if (!isTPHInConstraint(result, tph) && !isTphInEqualSet(result, tph)) { + HashSet equals = getEqualsTphsFromEqualCons(eqCons, tph); result.put(new ExtendsConstraint(tph, Type.getInternalName(Object.class), Relation.EXTENDS), equals); } } - - System.out.println("EndResult: "); - result.forEach((c,hs)->{ - if(c!=null) { - System.out.print(c.toString() + " -> "); - if(hs == null) { - System.out.print(" [] "); - }else { - hs.forEach(s->{ - System.out.print(s + ", "); - }); - } - } - - - System.out.println(); - }); - System.out.println("----------------"); - return result; - } - - - private static void updateEqualCons(Map> replRes, ArrayList eqCons) { - List oldNames = replRes.values().iterator().next(); - String newName = replRes.keySet().iterator().next(); - for(TPHConstraint c : eqCons) { -// if(oldNames.contains(c.getLeft())) -// c.setLeft(newName); - if(oldNames.contains(c.getRight())) - c.setRight(newName); - } - - } - - public static HashMap> simplifyConstraintsClass(TPHExtractor tphExtractor, ArrayList tphsClass) { - // all constraints that will be simplified - ArrayList allCons = tphExtractor.allCons; - ArrayList consToRemove = new ArrayList<>(); - - // step 1: - for(TPHConstraint c : allCons) { - - String left = c.getLeft(); - String right = c.getRight(); - if(c.getRel() == Relation.EXTENDS) { - TPHConstraint revCon = getReverseConstraint(allCons,left,right); - if(revCon != null) { - revCon.setRel(Relation.EQUAL); - // the reverse constraint is removed because - // otherwise there is the same constraint twice - // (e.g. A A=B and B=A) - consToRemove.add(revCon); - c.setRel(Relation.EQUAL); - substituteTPH(allCons,left, right); - } - } - } - - - allCons.removeAll(consToRemove); - consToRemove = new ArrayList<>(); - - int size = allCons.size(); - - HashMap> result = new HashMap<>(); - - // check if there is any long cycle (e.g. A 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 constraints = new ArrayList<>(size); - int visited = 0; - - // contains all constraints - HashMap 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 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 + // 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())) { + for (TPHConstraint c : allCons) { + if (c.getRel() == Relation.EQUAL) { + if (!isTPHInResEqual(result, c.getLeft())) { HashSet equalTPHs = getEqualsTPHs(result, c); - TPHConstraint constraint = getKeyConstraint(result,c); + TPHConstraint constraint = getKeyConstraint(result, c); equalTPHs.add(c.getLeft()); equalTPHs.add(c.getRight()); result.put(constraint, equalTPHs); @@ -521,131 +425,290 @@ public class Simplify { size--; } } - + // remove all equal-constraints allCons.removeAll(consToRemove); - // add all generated constraints to allCons + // 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); - result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS), null); - } - - return result; - } - - 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) { - if(c.getRight().equals(Type.getInternalName(Object.class))) - size--; - } - - // 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 subAndSuper = new HashMap<>(); - ArrayList eqCons = new ArrayList<>(); - for(TPHConstraint c : allCons) { - - subAndSuper.put(c.getLeft(), c.getRight()); - } - - int numOfVisitedPairs = 0; - for(String sub : subAndSuper.keySet()) { - if(isTPHInConstraint(result,sub)) - continue; - - if(!classTPHSContainsTPH(tphsClass,sub)) - continue; - - if(numOfVisitedPairs>=size) - break; - LinkedList tphInRel = new LinkedList<>(); - tphInRel.add(sub); - String superT = subAndSuper.get(sub); - tphInRel.add(superT); - - numOfVisitedPairs++; - while(subAndSuper.containsKey(superT)) { - superT = subAndSuper.get(superT); - if(tphInRel.contains(superT)) { - break; - } - tphInRel.add(superT); - numOfVisitedPairs++; - } - - // Subtype - String subTphRes = tphInRel.getFirst(); - // Die größte Supertype - String superTphRes = tphInRel.getLast(); - - // if there is any constraint X < subTph, then - // add X at the beginning of the list. - while(subAndSuper.containsValue(subTphRes)) { - for(String tph : subAndSuper.keySet()) { - if(classTPHSContainsTPH(tphsClass,tph) && subAndSuper.get(tph).equals(subTphRes)) { - subTphRes = tph; - break; - } - } - if(subTphRes.equals(tphInRel.getFirst())) { - break; - } - - if(isTPHInConstraint(result, subTphRes)) - break; - - tphInRel.addFirst(subTphRes); - numOfVisitedPairs++; - } - - subTphRes = tphInRel.getFirst(); - - - - HashSet equals = getEqualsTphsFromEqualCons(eqCons,superTphRes); - result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals); - - } - + System.out.println("EndResult: "); - result.forEach((c,hs)->{ - if(c!=null) { + result.forEach((c, hs) -> { + if (c != null) { System.out.print(c.toString() + " -> "); - if(hs == null) { + if (hs == null) { System.out.print(" [] "); - }else { - hs.forEach(s->{ + } else { + hs.forEach(s -> { System.out.print(s + ", "); }); } } - - + System.out.println(); }); System.out.println("----------------"); return result; } - - + + private static void updateEqualCons(Map> replRes, ArrayList eqCons) { + List oldNames = replRes.values().iterator().next(); + String newName = replRes.keySet().iterator().next(); + for (TPHConstraint c : eqCons) { +// if(oldNames.contains(c.getLeft())) +// c.setLeft(newName); + if (oldNames.contains(c.getRight())) + c.setRight(newName); + } + + } + + public static HashMap> simplifyConstraintsClass(TPHExtractor tphExtractor, + ArrayList tphsClass) { + // all constraints that will be simplified + ArrayList allCons = tphExtractor.allCons; + ArrayList consToRemove = new ArrayList<>(); + + // step 1: + for (TPHConstraint c : allCons) { + + String left = c.getLeft(); + String right = c.getRight(); + if (c.getRel() == Relation.EXTENDS) { + TPHConstraint revCon = getReverseConstraint(allCons, left, right); + if (revCon != null) { + revCon.setRel(Relation.EQUAL); + // the reverse constraint is removed because + // otherwise there is the same constraint twice + // (e.g. A A=B and B=A) + consToRemove.add(revCon); + c.setRel(Relation.EQUAL); + substituteTPH(allCons, left, right); + } + } + } + + allCons.removeAll(consToRemove); + consToRemove = new ArrayList<>(); + + int size = allCons.size(); + + HashMap> result = new HashMap<>(); + + // check if there is any long cycle (e.g. A 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 constraints = new ArrayList<>(size); + int visited = 0; + + // contains all constraints + HashMap 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 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) { + if (c.getRel() == Relation.EQUAL) { + if (!isTPHInResEqual(result, c.getLeft())) { + HashSet 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()); + + if (!allCons.isEmpty() && allCons.size() < 2) { + 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); + } + + return result; + } + + 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) { + if (c.getRight().equals(Type.getInternalName(Object.class))) + size--; + } + + // 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 subAndSuper = new HashMap<>(); + ArrayList eqCons = new ArrayList<>(); + for (TPHConstraint c : allCons) { + + subAndSuper.put(c.getLeft(), c.getRight()); + } + + int numOfVisitedPairs = 0; + for (String sub : subAndSuper.keySet()) { + if (isTPHInConstraint(result, sub)) + continue; + + if (!classTPHSContainsTPH(tphsClass, sub)) + continue; + + if (numOfVisitedPairs >= size) + break; + LinkedList tphInRel = new LinkedList<>(); + tphInRel.add(sub); + String superT = subAndSuper.get(sub); + tphInRel.add(superT); + + numOfVisitedPairs++; + while (subAndSuper.containsKey(superT)) { + superT = subAndSuper.get(superT); + if (tphInRel.contains(superT)) { + break; + } + tphInRel.add(superT); + numOfVisitedPairs++; + } + + // Subtype + String subTphRes = tphInRel.getFirst(); + // Die größte Supertype + String superTphRes = tphInRel.getLast(); + + // if there is any constraint X < subTph, then + // add X at the beginning of the list. + while (subAndSuper.containsValue(subTphRes)) { + for (String tph : subAndSuper.keySet()) { + if (classTPHSContainsTPH(tphsClass, tph) && subAndSuper.get(tph).equals(subTphRes)) { + subTphRes = tph; + break; + } + } + if (subTphRes.equals(tphInRel.getFirst())) { + break; + } + + if (isTPHInConstraint(result, subTphRes)) + break; + + tphInRel.addFirst(subTphRes); + numOfVisitedPairs++; + } + + subTphRes = tphInRel.getFirst(); + + HashSet equals = getEqualsTphsFromEqualCons(eqCons, superTphRes); + result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals); + + } + + System.out.println("EndResult: "); + result.forEach((c, hs) -> { + if (c != null) { + System.out.print(c.toString() + " -> "); + if (hs == null) { + System.out.print(" [] "); + } else { + hs.forEach(s -> { + System.out.print(s + ", "); + }); + } + } + + System.out.println(); + }); + System.out.println("----------------"); + return result; + } + private static boolean classTPHSContainsTPH(ArrayList tphsClass, String superTphRes) { - for(TypePlaceholder tph : tphsClass) { - if(tph.getName().equals(superTphRes)) + for (TypePlaceholder tph : tphsClass) { + if (tph.getName().equals(superTphRes)) return true; } return false; } private static boolean isTphInEqualSet(HashMap> result, String tph) { - for(HashSet hs: result.values()) { - if(hs.contains(tph)) + for (HashSet hs : result.values()) { + if (hs.contains(tph)) return true; } return false; @@ -653,44 +716,44 @@ public class Simplify { private static HashSet getEqualsTphsFromEqualCons(ArrayList eqCons, String tph) { HashSet ee = new HashSet<>(); - for(TPHConstraint c : eqCons) { - if(c.getLeft().equals(tph)) + for (TPHConstraint c : eqCons) { + if (c.getLeft().equals(tph)) ee.add(c.getRight()); - if(c.getRight().equals(tph)) + if (c.getRight().equals(tph)) ee.add(c.getLeft()); } return ee; } - private static void substituteInMap(HashMap subAndSuper, ArrayList allCons,ArrayList eqCons, String toSubs, - String tph) { + private static void substituteInMap(HashMap subAndSuper, ArrayList allCons, + ArrayList eqCons, String toSubs, String tph) { substituteTPH(allCons, toSubs, tph); - if(subAndSuper.containsKey(toSubs) && subAndSuper.containsKey(tph)) { + if (subAndSuper.containsKey(toSubs) && subAndSuper.containsKey(tph)) { toSubs = subAndSuper.remove(toSubs); EqualConstraint eq = new EqualConstraint(subAndSuper.get(tph), toSubs, Relation.EQUAL); eqCons.add(eq); - substituteInMap(subAndSuper, allCons,eqCons,toSubs, subAndSuper.get(tph)); - } else if(subAndSuper.containsKey(toSubs) && !subAndSuper.containsKey(tph)) { + substituteInMap(subAndSuper, allCons, eqCons, toSubs, subAndSuper.get(tph)); + } else if (subAndSuper.containsKey(toSubs) && !subAndSuper.containsKey(tph)) { String val = subAndSuper.remove(toSubs); subAndSuper.put(tph, val); } else { - for(String k : subAndSuper.keySet()) { + for (String k : subAndSuper.keySet()) { subAndSuper.replace(k, toSubs, tph); } } } private static TPHConstraint getConstraint(String oldRight, String right, ArrayList allCons) { - for(TPHConstraint c : allCons) { - if(c.getLeft().equals(oldRight) && c.getRight().equals(right)) + for (TPHConstraint c : allCons) { + if (c.getLeft().equals(oldRight) && c.getRight().equals(right)) return c; } return null; } private static boolean isTPHInResEqual(HashMap> result, String left) { - for(HashSet eq : result.values()) { - if(eq.contains(left)) { + for (HashSet eq : result.values()) { + if (eq.contains(left)) { return true; } } @@ -699,75 +762,77 @@ public class Simplify { private static void substituteAllTPH(ArrayList allCons, ArrayList 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())) + 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())) + if (c2.getLeft().equals(c.getRight()) || c2.getRight().equals(c.getRight())) c.setRight(first); } - + } } } private static void setAllEqual(ArrayList constraints) { - for(TPHConstraint c:constraints) { + for (TPHConstraint c : constraints) { c.setRel(Relation.EQUAL); } } - public static HashMap> simplifyContraints(HashMap> allConstraints) { + public static HashMap> simplifyContraints( + HashMap> allConstraints) { // 1. check if there are any cycles like L 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 .. - // a) yes => put all such TPhs in a map and define "key-Cons" - // -- key-Cons = TPH < Object -- - // put this Constraint and the - // b) no + // 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 .. + // a) yes => put all such TPhs in a map and define "key-Cons" + // -- key-Cons = TPH < Object -- + // put this Constraint and the + // b) no // 3. is ArrayList allCons = new ArrayList<>(); - for(TPHConstraint tphCons : allConstraints.keySet()) { + for (TPHConstraint tphCons : allConstraints.keySet()) { allCons.add(tphCons); } ArrayList consToRemove = new ArrayList<>(); // step 1: - for(TPHConstraint c : allCons) { - + for (TPHConstraint c : allCons) { + String left = c.getLeft(); String right = c.getRight(); - if(c.getRel() == Relation.EXTENDS) { - TPHConstraint revCon = getReverseConstraint(allCons,left,right); - if(revCon != null) { + if (c.getRel() == Relation.EXTENDS) { + TPHConstraint revCon = getReverseConstraint(allCons, left, right); + if (revCon != null) { revCon.setRel(Relation.EQUAL); consToRemove.add(revCon); c.setRel(Relation.EQUAL); - substituteTPH(allCons,left, right); + substituteTPH(allCons, left, right); } } } System.out.println(); System.out.println("NEW ALL CONST: " + allCons.size()); - allCons.forEach(c->System.out.println(c.toString())); + allCons.forEach(c -> System.out.println(c.toString())); System.out.println("----------------"); allCons.removeAll(consToRemove); consToRemove = new ArrayList<>(); - + // int size = allCons.size(); - + System.out.println("AFTER DELETE ALL CONST: " + allCons.size()); - allCons.forEach(c->System.out.println(c.toString())); + allCons.forEach(c -> System.out.println(c.toString())); System.out.println("----------------"); HashMap> result = new HashMap<>(); - - for(TPHConstraint c : allCons) { - if(c.getRel()==Relation.EQUAL) { + + for (TPHConstraint c : allCons) { + if (c.getRel() == Relation.EQUAL) { HashSet equalTPHs = getEqualsTPHs(result, c); - TPHConstraint constraint = getKeyConstraint(result,c); + TPHConstraint constraint = getKeyConstraint(result, c); equalTPHs.add(c.getLeft()); equalTPHs.add(c.getRight()); result.put(constraint, equalTPHs); @@ -776,9 +841,9 @@ public class Simplify { } } System.out.println("Step 2 Result: "); - result.forEach((c,hs)->{ + result.forEach((c, hs) -> { System.out.print(c.toString() + " -> "); - hs.forEach(s->{ + hs.forEach(s -> { System.out.print(s + ", "); }); System.out.println(); @@ -786,33 +851,33 @@ public class Simplify { System.out.println("----------------"); allCons.removeAll(consToRemove); allCons.addAll(result.keySet()); - - if(!allCons.isEmpty() && allCons.size()<2) { - if(!result.containsKey(allCons.get(0))) + if (!allCons.isEmpty() && allCons.size() < 2) { + + if (!result.containsKey(allCons.get(0))) result.put(allCons.get(0), null); - + return result; } - + // size += result.keySet().size(); - + // for(TPHConstraint c : allCons) { // if(c.getRight().equals(Type.getInternalName(Object.class))) // size--; // } - + HashMap subAndSuper = new HashMap<>(); - - for(TPHConstraint c : allCons) { + + for (TPHConstraint c : allCons) { subAndSuper.put(c.getLeft(), c.getRight()); } - + // int numOfVisitedPairs = 0; - for(String sub : subAndSuper.keySet()) { - if(isTPHInConstraint(result,sub)) + for (String sub : subAndSuper.keySet()) { + if (isTPHInConstraint(result, sub)) continue; - + // if(numOfVisitedPairs>=size) // break; @@ -820,118 +885,137 @@ public class Simplify { tphInRel.add(sub); String superT = subAndSuper.get(sub); tphInRel.add(superT); - + // numOfVisitedPairs++; - while(subAndSuper.containsKey(superT)) { + while (subAndSuper.containsKey(superT)) { superT = subAndSuper.get(superT); - if(tphInRel.contains(superT)) { + if (tphInRel.contains(superT)) { break; } tphInRel.add(superT); // numOfVisitedPairs++; } - + // Subtype String subTphRes = tphInRel.getFirst(); // Die größte Supertype String superTphRes = tphInRel.getLast(); - - while(subAndSuper.containsValue(subTphRes)) { - for(String tph : subAndSuper.keySet()) { - if(subAndSuper.get(tph).equals(subTphRes)) { + + while (subAndSuper.containsValue(subTphRes)) { + for (String tph : subAndSuper.keySet()) { + if (subAndSuper.get(tph).equals(subTphRes)) { subTphRes = tph; break; } } - if(subTphRes.equals(tphInRel.getFirst())) { + if (subTphRes.equals(tphInRel.getFirst())) { break; } tphInRel.addFirst(subTphRes); // numOfVisitedPairs++; } - + subTphRes = tphInRel.getFirst(); - + int i = 2; - while(superTphRes.equals(Type.getInternalName(Object.class)) && (tphInRel.size()-i) >0) { - superTphRes = tphInRel.get(tphInRel.size()-i); + while (superTphRes.equals(Type.getInternalName(Object.class)) && (tphInRel.size() - i) > 0) { + superTphRes = tphInRel.get(tphInRel.size() - i); i++; } - if(superTphRes.equals(Type.getInternalName(Object.class))) { - result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null); + if (superTphRes.equals(Type.getInternalName(Object.class))) { + 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); } - + } System.out.println("EndResult: "); - result.forEach((c,hs)->{ - if(c!=null) { + result.forEach((c, hs) -> { + if (c != null) { System.out.print(c.toString() + " -> "); - if(hs == null) { + if (hs == null) { System.out.print(" [] "); - }else { - hs.forEach(s->{ + } else { + hs.forEach(s -> { System.out.print(s + ", "); }); } } - - + System.out.println(); }); System.out.println("----------------"); return result; } - - private static void substituteTPH(ArrayList allCons,String left ,String right) { - allCons.forEach(c->{ - if(c.getRel() == Relation.EXTENDS) { - if(c.getLeft().equals(left)) + + private static void substituteTPH(ArrayList allCons, String left, String right) { + allCons.forEach(c -> { + if (c.getRel() == Relation.EXTENDS) { + if (c.getLeft().equals(left)) c.setLeft(right); - if(c.getRight().equals(left)) + if (c.getRight().equals(left)) c.setRight(right); } }); } private static TPHConstraint getReverseConstraint(ArrayList allCons, String left, String right) { - for(TPHConstraint c : allCons) { - if(c.getLeft().equals(right) && c.getRight().equals(left)){ + for (TPHConstraint c : allCons) { + if (c.getLeft().equals(right) && c.getRight().equals(left)) { return c; } } return null; } - + private static boolean isTPHInConstraint(HashMap> result, String sub) { - for(TPHConstraint c : result.keySet()) { - if(c.getLeft().equals(sub)) + for (TPHConstraint c : result.keySet()) { + if (c.getLeft().equals(sub)) return true; } return false; } private static boolean containTPH(ArrayList methodTphs, String sub) { - for(String tph : methodTphs) { - if(tph.equals(sub)) + for (String tph : methodTphs) { + if (tph.equals(sub)) return true; } return false; } - private static TPHConstraint getKeyConstraint(HashMap> result, TPHConstraint toFind) { - for(TPHConstraint c : result.keySet()) { - if(c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight())) + private static TPHConstraint getKeyConstraint(HashMap> result, TPHConstraint toFind, + ArrayList 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 HashSet getEqualsTPHs(HashMap> result, TPHConstraint toFind) { - for(TPHConstraint c : result.keySet()) { - if(c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight())) + private static TPHConstraint getKeyConstraint(HashMap> 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); + } + + private static HashSet getEqualsTPHs(HashMap> result, TPHConstraint toFind) { + for (TPHConstraint c : result.keySet()) { + if (c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight())) return result.get(c); } return new HashSet<>(); diff --git a/src/test/java/bytecode/KompTphTest.java b/src/test/java/bytecode/KompTphTest.java new file mode 100644 index 00000000..8fca0c0b --- /dev/null +++ b/src/test/java/bytecode/KompTphTest.java @@ -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(); + } + +} diff --git a/src/test/resources/bytecode/javFiles/KompTph.jav b/src/test/resources/bytecode/javFiles/KompTph.jav new file mode 100644 index 00000000..ec34e154 --- /dev/null +++ b/src/test/resources/bytecode/javFiles/KompTph.jav @@ -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); + } +} \ No newline at end of file From 5722f0285b439eb5439ea12af960caed0ac146f8 Mon Sep 17 00:00:00 2001 From: Michael Uhl Date: Sun, 24 Feb 2019 15:06:34 +0100 Subject: [PATCH 17/19] Skip tests in maven build. --- pom.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pom.xml b/pom.xml index 3541ad9b..b90b76e2 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,14 @@ http://maven.apache.org/maven-v4_0_0.xsd"> ${project.artifactId}-${project.version} target/test-classes + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M3 + + true + + org.antlr antlr4-maven-plugin From 8a5dbb28acc872b779d2bb7d3b42e18a492f0c73 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Mon, 25 Feb 2019 19:20:11 +0100 Subject: [PATCH 18/19] Bug gefixt: genericList als Paramater uebergeben --- .../de/dhbwstuttgart/bytecode/BytecodeGenMethod.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index dd3d27ed..b1ea614f 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -140,7 +140,8 @@ public class BytecodeGenMethod implements StatementVisitor { } public BytecodeGenMethod(LambdaExpression lambdaExpression, ArrayList usedVars, ResultSet resultSet, MethodVisitor mv, - int indexOfFirstParamLam, boolean isInterface, HashMap classFiles, String path, int lamCounter, SourceFile sf) { + int indexOfFirstParamLam, boolean isInterface, HashMap classFiles, String path, int lamCounter, SourceFile sf,HashMap genericsAndBoundsMethod, + HashMap genericsAndBounds) { this.resultSet = resultSet; this.mv = mv; @@ -149,6 +150,9 @@ public class BytecodeGenMethod implements StatementVisitor { this.path = path; this.lamCounter = lamCounter; this.sf = sf; + this.genericsAndBoundsMethod = genericsAndBoundsMethod; + this.genericsAndBounds = genericsAndBounds; + Iterator itr = lambdaExpression.params.iterator(); int i = indexOfFirstParamLam; @@ -644,7 +648,8 @@ public class BytecodeGenMethod implements StatementVisitor { ArrayList usedVars = kindOfLambda.getUsedVars(); new BytecodeGenMethod(lambdaExpression, usedVars,this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface, - classFiles,this.path, lamCounter, sf); + classFiles,this.path, lamCounter, sf, genericsAndBoundsMethod, + genericsAndBounds); mvLambdaBody.visitMaxs(0, 0); mvLambdaBody.visitEnd(); From 4d4be5420b61f186944336ccb89e2a45b11c8679 Mon Sep 17 00:00:00 2001 From: Michael Uhl Date: Fri, 15 Mar 2019 10:52:31 +0100 Subject: [PATCH 19/19] Anpassung asynchroner Aufruf des Plugins ======================================== MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UnifyResultListener muss übergeben werden, da sonst Ergebnisse gemeldet werden (notify), ohne dass das Plugin als UnifyResultListener registriert wurde. --- src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java index fd570a0c..b84c9441 100644 --- a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -34,6 +34,7 @@ import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask; +import de.dhbwstuttgart.typeinference.unify.UnifyResultListener; import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl; import de.dhbwstuttgart.typeinference.unify.UnifyResultModel; @@ -277,7 +278,7 @@ public class JavaTXCompiler { } */ - public UnifyResultModel typeInferenceAsync() throws ClassNotFoundException { + public UnifyResultModel typeInferenceAsync(UnifyResultListener resultListener) throws ClassNotFoundException { List allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); //Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC for(SourceFile sf : this.sourceFiles.values()) { @@ -288,6 +289,7 @@ public class JavaTXCompiler { final ConstraintSet cons = getConstraints(); Set> results = new HashSet<>(); UnifyResultModel urm = new UnifyResultModel(); + urm.addUnifyResultListener(resultListener); try { Writer logFile = new OutputStreamWriter(new NullOutputStream()); //new FileWriter(new File("log_"+sourceFiles.keySet().iterator().next().getName()));