From 94b93c39df15491544fe7eaccd0b356fa0aa4e9f Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 17 Oct 2018 14:29:12 +0200 Subject: [PATCH 01/14] modified: src/de/dhbwstuttgart/bytecode/BytecodeGen.java modified: src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java new file: test/bytecode/FieldTest.java modified: test/bytecode/MatrixOpTest.java new file: test/bytecode/javFiles/Field.jav modified: test/bytecode/javFiles/Sorting.jav Boxing-Problem bei methodCall geloest und Tests funktionieren --- .../dhbwstuttgart/bytecode/BytecodeGen.java | 4 +- .../bytecode/BytecodeGenMethod.java | 27 ++++++++---- test/bytecode/FieldTest.java | 43 +++++++++++++++++++ test/bytecode/MatrixOpTest.java | 6 +-- test/bytecode/javFiles/Field.jav | 4 ++ test/bytecode/javFiles/Sorting.jav | 2 +- 6 files changed, 72 insertions(+), 14 deletions(-) create mode 100644 test/bytecode/FieldTest.java create mode 100644 test/bytecode/javFiles/Field.jav diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index f54c6779e..f434db232 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -471,6 +471,7 @@ public class BytecodeGen implements ASTVisitor { // ?? @Override public void visit(FieldVar fieldVar) { + System.out.println("In FieldVar ---"); // cw.newField(fieldVar.receiver.toString(), fieldVar.fieldVarName.toString(), fieldVar.getType().toString()); FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, fieldVar.fieldVarName, "L"+fieldVar.getType()+";", null, null); fv.visitEnd(); @@ -479,7 +480,8 @@ public class BytecodeGen implements ASTVisitor { // access flages?? modifiers @Override public void visit(Field field) { - FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, field.getName(), "L"+field.getType().toString().replace(".", "/")+";", null, null); + System.out.println("In Field ---"); + FieldVisitor fv = cw.visitField(field.modifier, field.getName(),resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToDescriptor()), null, null); fv.visitEnd(); } diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index e35127ed7..962fb6da8 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -71,6 +71,7 @@ public class BytecodeGenMethod implements StatementVisitor { private SourceFile sf; private IStatement statement = null; private boolean isReturnStmt = false; + private boolean isParentBinary = false; private boolean needDUP = false; @@ -211,7 +212,7 @@ public class BytecodeGenMethod implements StatementVisitor { @Override public void visit(BinaryExpr binary) { - + isParentBinary = true; String lexpType = getResolvedType(binary.lexpr.getType()); String rexpType = getResolvedType(binary.rexpr.getType()); @@ -242,12 +243,14 @@ public class BytecodeGenMethod implements StatementVisitor { needDUP = true; binary.rexpr.accept(this); - + + isParentBinary = false; + if (!lexpType.equals(rexpType) && !rexpType.equals(largerType)) doCast(rexpType, largerType); Operator op = binary.operation; - + switch (op) { case ADD: doVisitAddOpInsn(largerType); @@ -665,6 +668,7 @@ public class BytecodeGenMethod implements StatementVisitor { @Override public void visit(MethodCall methodCall) { + boolean parentBinary = isParentBinary; System.out.println("In MethodCall = " + methodCall.name); String receiverName = getResolvedType(methodCall.receiver.getType()); System.out.println("Methods of " + receiverName + " "); @@ -681,7 +685,7 @@ public class BytecodeGenMethod implements StatementVisitor { java.lang.reflect.Method[] methods = cLoader.loadClass(clazz).getMethods(); System.out.println("Methods of " + receiverName + " "); - methodRefl = getMethod(methodCall.name,methods); + methodRefl = getMethod(methodCall.name,methodCall.arglist.getArguments().size(),methods); } catch (Exception e) { // try { @@ -736,16 +740,19 @@ public class BytecodeGenMethod implements StatementVisitor { System.out.println("Methodcall type : " + resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor())); String mDesc = ""; List argListMethCall = new LinkedList<>(); + String receiverRefl=""; if(methodRefl == null) { MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(), receiverName, genericsAndBoundsMethod, genericsAndBounds); mDesc = method.accept(new DescriptorToString(resultSet)); methodCall.arglist.accept(this); } else { + receiverRefl = methodRefl.getAnnotatedReceiverType().getType().toString(); for(Parameter p:methodRefl.getParameters()) { System.out.println(p.getName() + " und is Primitive = " + p.getType().isPrimitive()); argListMethCall.add(p.getType().isPrimitive()); } + System.out.println("Receiver = " + methodRefl.getAnnotatedReceiverType().getType().toString()); mDesc = getMethodDesc(methodRefl); for (Expression al : methodCall.arglist.getArguments()) { statement = new ArgumentExpr(al); @@ -761,7 +768,7 @@ public class BytecodeGenMethod implements StatementVisitor { // methodCall.arglist.accept(this); // is methodCall.receiver functional Interface)? - if (varsFunInterface.contains(methodCall.receiver.getType())) { + if (varsFunInterface.contains(methodCall.receiver.getType()) || (methodRefl!= null && receiverRefl.contains("interface"))) { mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, clazz.replace(".", "/"), methodCall.name, mDesc, true); } else { @@ -780,8 +787,8 @@ public class BytecodeGenMethod implements StatementVisitor { if(isBinaryExp) doUnboxing(getResolvedType(methodCall.getType())); } - - if(methodRefl == null/* && !isReturnStmt*/) { + System.out.println("ISParent Binary = "+isParentBinary +" -> " + parentBinary); + if(methodRefl == null && (parentBinary || !isReturnStmt)) { if(isBinaryExp) doUnboxing(getResolvedType(methodCall.getType())); } @@ -790,12 +797,13 @@ public class BytecodeGenMethod implements StatementVisitor { /** * @param name name of a method + * @param i number of parameters * @param methods all methods of a class * @return the method in the class file which its name equals the given methode name */ - private java.lang.reflect.Method getMethod(String name, java.lang.reflect.Method[] methods) { + private java.lang.reflect.Method getMethod(String name, int i, java.lang.reflect.Method[] methods) { for(java.lang.reflect.Method m : methods) { - if(name.equals(m.getName())) { + if(name.equals(m.getName()) && i == m.getParameterCount()) { return m; } } @@ -1252,6 +1260,7 @@ public class BytecodeGenMethod implements StatementVisitor { // array slot onto the top of the operand stack. assignLeftSide.field.receiver.accept(this); this.rightSideTemp.accept(this); + System.out.println("Receiver = " + getResolvedType(assignLeftSide.field.receiver.getType())); mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()), assignLeftSide.field.fieldVarName, getResolvedType(assignLeftSide.field.getType())); } diff --git a/test/bytecode/FieldTest.java b/test/bytecode/FieldTest.java new file mode 100644 index 000000000..a5528b00b --- /dev/null +++ b/test/bytecode/FieldTest.java @@ -0,0 +1,43 @@ +package bytecode; + +import static org.junit.Assert.*; + +import java.io.File; +import java.lang.reflect.Field; + +import org.junit.BeforeClass; +import org.junit.Test; +import java.net.URL; +import java.net.URLClassLoader; + +import de.dhbwstuttgart.core.JavaTXCompiler; + +public class FieldTest { + + 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")+"/test/bytecode/javFiles/Field.jav"; + fileToTest = new File(path); + compiler = new JavaTXCompiler(fileToTest); + compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/"); + pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/"; + loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); + classToTest = loader.loadClass("Field"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + } + + @Test + public void test() { + Field[] fields = classToTest.getFields(); + assertEquals(1, fields.length); + } + +} diff --git a/test/bytecode/MatrixOpTest.java b/test/bytecode/MatrixOpTest.java index 178aa43e5..8fe538aaf 100644 --- a/test/bytecode/MatrixOpTest.java +++ b/test/bytecode/MatrixOpTest.java @@ -32,9 +32,9 @@ public class MatrixOpTest { fileToTest = new File(path); compiler = new JavaTXCompiler(fileToTest); pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/"; - compiler.generateBytecode(pathToClassFile); - loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); - classToTest = loader.loadClass("MatrixOP"); +// compiler.generateBytecode(pathToClassFile); +// loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); +// classToTest = loader.loadClass("MatrixOP"); /* Vector> vv = new Vector>(); Vector v1 = new Vector (); diff --git a/test/bytecode/javFiles/Field.jav b/test/bytecode/javFiles/Field.jav new file mode 100644 index 000000000..ed08efce2 --- /dev/null +++ b/test/bytecode/javFiles/Field.jav @@ -0,0 +1,4 @@ + +public class Field { + x = 5; +} \ No newline at end of file diff --git a/test/bytecode/javFiles/Sorting.jav b/test/bytecode/javFiles/Sorting.jav index 0c76fa2e0..341a1a6b2 100644 --- a/test/bytecode/javFiles/Sorting.jav +++ b/test/bytecode/javFiles/Sorting.jav @@ -2,7 +2,7 @@ import java.util.List; import java.util.ArrayList; import java.lang.String; -class Sorting{ +public class Sorting{ merge(a, b){ a.addAll(b); return a; From e3f2e4d79320fa90e62cc69dbf6bddf9c98d1ad7 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Thu, 18 Oct 2018 19:53:41 +0200 Subject: [PATCH 02/14] Alle Tests funktionieren --- .../dhbwstuttgart/bytecode/BytecodeGen.java | 18 +++++++++-- .../bytecode/BytecodeGenMethod.java | 7 ++-- .../typeinference/typeAlgo/TYPEStmt.java | 3 ++ test/bytecode/OverloadingSortingTest.java | 32 +++++++++---------- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index f434db232..8c9be088e 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -177,6 +177,21 @@ public class BytecodeGen implements ASTVisitor { public void visit(Constructor field) { field.getParameterList().accept(this); + String methParamTypes = field.name+"%%"; + + Iterator itr = field.getParameterList().iterator(); + while(itr.hasNext()) { + FormalParameter fp = itr.next(); + methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";"; +// methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";"; + } + + if(methodNameAndParamsT.contains(methParamTypes)) { + return; + } + methodNameAndParamsT.add(methParamTypes); + System.out.println("Method: "+field.name +" , paramsType: "+methParamTypes); + String desc = null; boolean hasGen = false; @@ -481,8 +496,7 @@ public class BytecodeGen implements ASTVisitor { @Override public void visit(Field field) { System.out.println("In Field ---"); - FieldVisitor fv = cw.visitField(field.modifier, field.getName(),resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToDescriptor()), null, null); - fv.visitEnd(); + cw.visitField(field.modifier, field.getName(),resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToSignature()), null, null); } @Override diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index 962fb6da8..ea3b3f30f 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -1095,13 +1095,16 @@ public class BytecodeGenMethod implements StatementVisitor { visitIntegerLiteral(((Integer) value).intValue(), false); break; case "java/lang/Long": - visitLongLiteral(((Double) value).longValue(), true); + visitLongLiteral(((Integer) value).longValue(), true); break; case "java/lang/Float": visitFloatLiteral(((Double) value).floatValue()); break; case "java/lang/Double": - visitDoubleLiteral((Double) value); + if(value instanceof Double) + visitDoubleLiteral((Double) value); + if(value instanceof Integer) + visitDoubleLiteral(((Integer) value).doubleValue()); break; case "java/lang/Character": visitCharLiteral((Character) value); diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index 5a9085cd1..edee20ac1 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -387,6 +387,9 @@ public class TYPEStmt implements StatementVisitor{ oderConstraints.add(constraint); constraint = new Constraint(); constraint.add(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT)); + oderConstraints.add(constraint); + constraint = new Constraint(); + constraint.add(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT)); oderConstraints.add(constraint); constraintsSet.addOderConstraint(oderConstraints); // */ diff --git a/test/bytecode/OverloadingSortingTest.java b/test/bytecode/OverloadingSortingTest.java index a781280f8..c6df11cdb 100644 --- a/test/bytecode/OverloadingSortingTest.java +++ b/test/bytecode/OverloadingSortingTest.java @@ -24,28 +24,28 @@ public class OverloadingSortingTest { private static Class classOL2; private static Object instanceOfClassOL2; - @BeforeClass - public static void setUpBeforeClass() throws Exception { + @Test + public void generateBC() throws Exception { path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Sorting.jav"; fileToTest = new File(path); compiler = new JavaTXCompiler(fileToTest); pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/"; compiler.generateBytecode(pathToClassFile); - loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); - classToTest = loader.loadClass("Sorting"); - instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); +// loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); +// classToTest = loader.loadClass("Sorting"); +// instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); } - @Test - public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - Method meth = classToTest.getDeclaredMethod("merge", classToTest); - } - - @Test - public void test2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - Method meth = classToTest.getDeclaredMethod("test", classOL2); - String res = (String) meth.invoke(instanceOfClass, instanceOfClassOL2); - assertEquals("Overloading2", res); - } +// @Test +// public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { +// Method meth = classToTest.getDeclaredMethod("merge", classToTest); +// } +// +// @Test +// public void test2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { +// Method meth = classToTest.getDeclaredMethod("test", classOL2); +// String res = (String) meth.invoke(instanceOfClass, instanceOfClassOL2); +// assertEquals("Overloading2", res); +// } } From d4c17053d7ab5f9ab359840de82806c35bf8f44a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Wed, 24 Oct 2018 15:36:20 +0200 Subject: [PATCH 03/14] modified: ../../src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit public void visit(AssignToField assignLeftSide) { //Hier ist kein Code nötig. Es werden keine extra Constraints generiert //HIER muss Code rein PL 2018-10-24 assignLeftSide.field.accept(this); eingefuegt } --- src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index edee20ac1..ea3616eb3 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -487,6 +487,8 @@ public class TYPEStmt implements StatementVisitor{ @Override public void visit(AssignToField assignLeftSide) { //Hier ist kein Code nötig. Es werden keine extra Constraints generiert + //HIER muss Code rein PL 2018-10-24 + assignLeftSide.field.accept(this); } @Override From 7a1ed7ce6f7f1ef1ccb8f07a2f72919a080ddb20 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Thu, 25 Oct 2018 12:26:56 +0200 Subject: [PATCH 04/14] Neuer Transivitaet-Algorithmus Step 1 und Step 2 --- .../dhbwstuttgart/bytecode/BytecodeGen.java | 155 +++++++++++++++++- .../bytecode/constraint/EqualConstraint.java | 9 + .../constraint/ExtendsConstraint.java | 9 + .../bytecode/constraint/TPHConstraint.java | 55 +++++++ test/bytecode/javFiles/Field.jav | 5 + 5 files changed, 230 insertions(+), 3 deletions(-) create mode 100644 src/de/dhbwstuttgart/bytecode/constraint/EqualConstraint.java create mode 100644 src/de/dhbwstuttgart/bytecode/constraint/ExtendsConstraint.java create mode 100644 src/de/dhbwstuttgart/bytecode/constraint/TPHConstraint.java diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index 8c9be088e..62fb86ce8 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -2,6 +2,7 @@ package de.dhbwstuttgart.bytecode; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -13,6 +14,9 @@ import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; +import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint; +import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; +import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation; import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString; import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor; import de.dhbwstuttgart.bytecode.signature.Signature; @@ -175,6 +179,11 @@ public class BytecodeGen implements ASTVisitor { @Override public void visit(Constructor field) { + System.out.println("ResultSet: "); + resultSet.results.forEach(a->{ + System.out.println(a.getLeft().toString() + " = " + a.getRight().toString()); + }); + System.out.println("---------------"); field.getParameterList().accept(this); String methParamTypes = field.name+"%%"; @@ -205,7 +214,7 @@ public class BytecodeGen implements ASTVisitor { } String sig = null; if(hasGen) { - ArrayList pairs = simplifyPairs(field.name,tphExtractor.allPairs); + ArrayList pairs = simplifyPairs(field.name,tphExtractor.allPairs, tphExtractor.allCons); Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,pairs); sig = signature.toString(); } @@ -274,7 +283,11 @@ public class BytecodeGen implements ASTVisitor { /* if method has generics or return type is TPH, create signature */ // zwite operand muss weggelassen werden if(hasGen||resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString()).equals("TPH")) { - ArrayList pairs = simplifyPairs(method.name,tphExtractor.allPairs); + System.out.println("ALL CONST: " + tphExtractor.allCons.size()); + tphExtractor.allCons.forEach(c->System.out.println(c.toString())); + System.out.println("----------------"); + HashMap> constraints = simplifyPairs(method.name,tphExtractor.allCons); + ArrayList pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons); System.out.println(method.name + " => Simplified Pairs: "); pairs.forEach(p->System.out.println(p.TA1.getName() + " -> "+p.TA2.getName())); Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet, pairs); @@ -295,9 +308,122 @@ public class BytecodeGen implements ASTVisitor { mv.visitEnd(); } - private ArrayList simplifyPairs(String methodName, ArrayList allPairs) { + private HashMap> simplifyPairs(String name, ArrayList allCons) { + // 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 + // b) no + 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); + consToRemove.add(revCon); + c.setRel(Relation.EQUAL); + substituteTPH(allCons,left, right); + } + } + } + System.out.println(); + System.out.println("NEW ALL CONST: " + allCons.size()); + allCons.forEach(c->System.out.println(c.toString())); + System.out.println("----------------"); + allCons.removeAll(consToRemove); + System.out.println("AFTER DELETE ALL CONST: " + allCons.size()); + allCons.forEach(c->System.out.println(c.toString())); + System.out.println("----------------"); + HashMap> result = new HashMap<>(); + for(TPHConstraint c : allCons) { + if(c.getRel()==Relation.EQUAL) { + HashSet equalTPHs = getEqualsTPHs(result, c); + TPHConstraint constraint = getKeyConstraint(result,c); + equalTPHs.add(c.getLeft()); + equalTPHs.add(c.getRight()); + result.put(constraint, equalTPHs); + } + } + System.out.println("Step 2 Result: "); + result.forEach((c,hs)->{ + System.out.print(c.toString() + " -> "); + hs.forEach(s->{ + System.out.print(s + ", "); + }); + System.out.println(); + }); + System.out.println("----------------"); + return result; + } + + private 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 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<>(); + } + + private String getBound(ArrayList allCons, String right) { + String bound = Type.getInternalName(Object.class); + for(TPHConstraint c: allCons) { + if(c.getRel() == Relation.EXTENDS && c.getLeft().equals(right)) { + return c.getRight(); + } + } + return bound; + } + + private ArrayList simplifyPairs(String methodName, ArrayList allPairs, ArrayList allCons) { allPairs.forEach(p->System.out.print(p.TA1 + " < "+ p.TA2+ " ; ")); + // 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 + // b) no + 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); + consToRemove.add(revCon); + c.setRel(Relation.EQUAL); + substituteTPH(allCons,left, right); + } + } + } + System.out.println(); + System.out.println("NEW ALL CONST: " + allCons.size()); + allCons.forEach(c->System.out.println(c.toString())); + System.out.println("----------------"); + allCons.removeAll(consToRemove); + System.out.println("AFTER DELETE ALL CONST: " + allCons.size()); + allCons.forEach(c->System.out.println(c.toString())); + System.out.println("----------------"); if(allPairs.size() < 2) return allPairs; @@ -425,6 +551,26 @@ public class BytecodeGen implements ASTVisitor { return simplifiedPairs; } + private 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)) + c.setRight(right); + } + }); + } + + private TPHConstraint getReverseConstraint(ArrayList allCons, String left, String right) { + for(TPHConstraint c : allCons) { + if(c.getLeft().equals(right) && c.getRight().equals(left)){ + return c; + } + } + return null; + } + private void removePair(ArrayList simplifiedPairs, TypePlaceholder typePlaceholder, TypePlaceholder typePlaceholder2) { for(GenericInsertPair p : simplifiedPairs) { if(p.TA1.equals(typePlaceholder) && p.TA2.equals(typePlaceholder2)) { @@ -685,6 +831,7 @@ public class BytecodeGen implements ASTVisitor { Boolean inMethod = false; final ArrayList ListOfMethodsAndTph = new ArrayList<>(); final ArrayList allPairs = new ArrayList<>(); + final ArrayList allCons = new ArrayList<>(); @Override public void visit(TypePlaceholder tph) { @@ -699,6 +846,8 @@ public class BytecodeGen implements ASTVisitor { if(inMethod) methodAndTph.getPairs().add(ag); allPairs.add(ag); + TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS); + allCons.add(con); } }); } diff --git a/src/de/dhbwstuttgart/bytecode/constraint/EqualConstraint.java b/src/de/dhbwstuttgart/bytecode/constraint/EqualConstraint.java new file mode 100644 index 000000000..fb6cae207 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/constraint/EqualConstraint.java @@ -0,0 +1,9 @@ +package de.dhbwstuttgart.bytecode.constraint; + +public class EqualConstraint extends TPHConstraint { + + public EqualConstraint(String left, String right, Relation rel) { + super(left, right, rel); + } + +} diff --git a/src/de/dhbwstuttgart/bytecode/constraint/ExtendsConstraint.java b/src/de/dhbwstuttgart/bytecode/constraint/ExtendsConstraint.java new file mode 100644 index 000000000..6f28e24f2 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/constraint/ExtendsConstraint.java @@ -0,0 +1,9 @@ +package de.dhbwstuttgart.bytecode.constraint; + +public class ExtendsConstraint extends TPHConstraint { + + public ExtendsConstraint(String left, String right, Relation rel) { + super(left, right, rel); + } + +} diff --git a/src/de/dhbwstuttgart/bytecode/constraint/TPHConstraint.java b/src/de/dhbwstuttgart/bytecode/constraint/TPHConstraint.java new file mode 100644 index 000000000..e0f3b4c08 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/constraint/TPHConstraint.java @@ -0,0 +1,55 @@ +package de.dhbwstuttgart.bytecode.constraint; + +public class TPHConstraint { + protected String left; + protected String right; + protected Relation rel; + public enum Relation{ + EXTENDS, EQUAL + } + + public TPHConstraint(String left, String right, Relation rel) { + this.left = left; + this.right = right; + this.rel = rel; + } + + public String getLeft() { + return left; + } + + + public String getRight() { + return right; + } + + + public Relation getRel() { + return rel; + } + + public void setLeft(String left) { + this.left = left; + } + + public void setRight(String right) { + this.right = right; + } + + public void setRel(Relation rel) { + this.rel = rel; + } + + public boolean containTPH(String tph) { + return left.equals(tph)||right.equals(tph); + } + + @Override + public String toString() { + if(rel == Relation.EXTENDS) { + return left + " < " + right; + }else { + return left + " = " + right; + } + } +} diff --git a/test/bytecode/javFiles/Field.jav b/test/bytecode/javFiles/Field.jav index ed08efce2..970cbe2fd 100644 --- a/test/bytecode/javFiles/Field.jav +++ b/test/bytecode/javFiles/Field.jav @@ -1,4 +1,9 @@ +import java.lang.Integer; public class Field { x = 5; + + m(){ + return x; + } } \ No newline at end of file From 788ddb2bcc1066cd07d13b3cea1746969f7aeea3 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Thu, 25 Oct 2018 12:41:26 +0200 Subject: [PATCH 05/14] modified: src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java modified: test/bytecode/javFiles/Field.jav Field-Test funktioniert --- src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java | 2 +- test/bytecode/javFiles/Field.jav | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index ea3b3f30f..50ff9b0d5 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -1265,7 +1265,7 @@ public class BytecodeGenMethod implements StatementVisitor { this.rightSideTemp.accept(this); System.out.println("Receiver = " + getResolvedType(assignLeftSide.field.receiver.getType())); mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()), - assignLeftSide.field.fieldVarName, getResolvedType(assignLeftSide.field.getType())); + assignLeftSide.field.fieldVarName, "L"+getResolvedType(assignLeftSide.field.getType())+";"); } @Override diff --git a/test/bytecode/javFiles/Field.jav b/test/bytecode/javFiles/Field.jav index 970cbe2fd..b19b2308b 100644 --- a/test/bytecode/javFiles/Field.jav +++ b/test/bytecode/javFiles/Field.jav @@ -1,7 +1,7 @@ import java.lang.Integer; public class Field { - x = 5; + public Integer x = 5; m(){ return x; From a02e5a16a84b37a0c66c1f9970fe3d440c1d3f8f Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 31 Oct 2018 16:07:37 +0100 Subject: [PATCH 06/14] Transivitaet-Algo version 1 --- .../dhbwstuttgart/bytecode/BytecodeGen.java | 165 ++++++++++++++++-- test/bytecode/javFiles/Tph.jav | 2 +- 2 files changed, 154 insertions(+), 13 deletions(-) diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index 62fb86ce8..641db6dd0 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import de.dhbwstuttgart.exceptions.NotImplementedException; @@ -315,8 +316,11 @@ public class BytecodeGen implements ASTVisitor { // * 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 + // 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 consToRemove = new ArrayList<>(); // step 1: for(TPHConstraint c : allCons) { @@ -338,10 +342,15 @@ public class BytecodeGen implements ASTVisitor { 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())); System.out.println("----------------"); HashMap> result = new HashMap<>(); + for(TPHConstraint c : allCons) { if(c.getRel()==Relation.EQUAL) { HashSet equalTPHs = getEqualsTPHs(result, c); @@ -349,6 +358,8 @@ public class BytecodeGen implements ASTVisitor { equalTPHs.add(c.getLeft()); equalTPHs.add(c.getRight()); result.put(constraint, equalTPHs); + consToRemove.add(c); + size--; } } System.out.println("Step 2 Result: "); @@ -360,9 +371,150 @@ public class BytecodeGen implements ASTVisitor { System.out.println(); }); System.out.println("----------------"); + allCons.removeAll(consToRemove); + allCons.addAll(result.keySet()); + + if(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--; + } + + ArrayList methodTphs = new ArrayList<>(); + for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) { + if(m.getName().equals(name)) { + methodTphs = m.getTphs(); + break; + } + } + + HashMap subAndSuper = new HashMap<>(); + 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; + } + subAndSuper.put(c.getLeft(), c.getRight()); + } + + int numOfVisitedPairs = 0; + for(String sub : subAndSuper.keySet()) { + if(isTPHInConstraint(result,sub)) + continue; + + if(!containTPH(methodTphs,sub)) + continue; + + if(numOfVisitedPairs>=size) + break; + LinkedList tphInRel = new LinkedList<>(); + tphInRel.add(sub); + String superT = subAndSuper.get(sub); + tphInRel.add(superT); + + numOfVisitedPairs++; + boolean isCycle = false; + while(subAndSuper.containsKey(superT)) { + superT = subAndSuper.get(superT); + if(tphInRel.contains(superT)) { + isCycle = true; + 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(containTPH(methodTphs,tph) && subAndSuper.get(tph).equals(subTphRes)) { + subTphRes = tph; + break; + } + } + if(subTphRes.equals(tphInRel.getFirst())) { + break; + } + tphInRel.addFirst(subTphRes); + numOfVisitedPairs++; + } + + subTphRes = tphInRel.getFirst(); + + int i = 2; + while(!containTPH(methodTphs,superTphRes) && (tphInRel.size()-i) >0) { + superTphRes = tphInRel.get(tphInRel.size()-i); + i++; + } + + if(!containTPH(methodTphs, superTphRes)) { + 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); + } + } + System.out.println("ZwischenResult: "); + 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 boolean isTPHInConstraint(HashMap> result, String sub) { + for(TPHConstraint c : result.keySet()) { + if(c.getLeft().equals(sub)) + return true; + } + return false; + } + + private boolean containTPH(ArrayList methodTphs, String sub) { + for(TypePlaceholder tph : methodTphs) { + if(tph.getName().equals(sub)) + return true; + } + return false; + } + private TPHConstraint getKeyConstraint(HashMap> result, TPHConstraint toFind) { for(TPHConstraint c : result.keySet()) { if(c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight())) @@ -379,16 +531,6 @@ public class BytecodeGen implements ASTVisitor { return new HashSet<>(); } - private String getBound(ArrayList allCons, String right) { - String bound = Type.getInternalName(Object.class); - for(TPHConstraint c: allCons) { - if(c.getRel() == Relation.EXTENDS && c.getLeft().equals(right)) { - return c.getRight(); - } - } - return bound; - } - private ArrayList simplifyPairs(String methodName, ArrayList allPairs, ArrayList allCons) { allPairs.forEach(p->System.out.print(p.TA1 + " < "+ p.TA2+ " ; ")); @@ -638,7 +780,6 @@ public class BytecodeGen implements ASTVisitor { fv.visitEnd(); } - // access flages?? modifiers @Override public void visit(Field field) { System.out.println("In Field ---"); diff --git a/test/bytecode/javFiles/Tph.jav b/test/bytecode/javFiles/Tph.jav index 1160e1a55..9faa570cf 100644 --- a/test/bytecode/javFiles/Tph.jav +++ b/test/bytecode/javFiles/Tph.jav @@ -2,7 +2,7 @@ public class Tph { m(a,b){ var c = m2(b); - return c; + return a; // return m2(b); } From 27b73f55e7c2729e4b8f5dee06872df830ada553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Wed, 31 Oct 2018 16:59:53 +0100 Subject: [PATCH 07/14] modified: ../../src/de/dhbwstuttgart/typeinference/unify/RuleSet.java log-Ausgaben eingefuegt --- .../typeinference/unify/RuleSet.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java index a48b7db2e..e438d5003 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java @@ -792,6 +792,14 @@ public class RuleSet implements IRuleSet{ UnifyType r = x.getRhsType(); if (r instanceof PlaceholderType) { ((PlaceholderType)r).disableWildcardtable(); } } ); + try { + logFile.write("FUNgreater: " + pair + "\n"); + logFile.write("FUNred: " + result + "\n"); + logFile.flush(); + } + catch (IOException e) { + System.out.println("lofFile-Error"); + } return Optional.of(result); } @@ -834,6 +842,14 @@ public class RuleSet implements IRuleSet{ UnifyType r = x.getRhsType(); if (r instanceof PlaceholderType) { ((PlaceholderType)r).disableWildcardtable(); } } ); + try { + logFile.write("FUNgreater: " + pair + "\n"); + logFile.write("FUNgreater: " + result + "\n"); + logFile.flush(); + } + catch (IOException e) { + System.out.println("lofFile-Error"); + } return Optional.of(result); } @@ -876,6 +892,14 @@ public class RuleSet implements IRuleSet{ UnifyType r = x.getRhsType(); if (r instanceof PlaceholderType) { ((PlaceholderType)r).disableWildcardtable(); } } ); + try { + logFile.write("FUNgreater: " + pair + "\n"); + logFile.write("FUNsmaller: " + result + "\n"); + logFile.flush(); + } + catch (IOException e) { + System.out.println("lofFile-Error"); + } return Optional.of(result); } From 4ef360e41eb0fc48c9af7364e0bf3bef08d5e07a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Fri, 2 Nov 2018 22:53:34 +0100 Subject: [PATCH 08/14] modified: ../../src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java modified: ../../src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java FieldVars eingefuegt, dass sie genauso wie localsvars immer die gleiche Typvariable in der abstrakten Syntax bekommen --- .../SyntaxTreeGenerator/StatementGenerator.java | 13 ++++++++++--- .../SyntaxTreeGenerator/SyntaxTreeGenerator.java | 6 ++++-- .../typeinference/typeAlgo/TYPEStmt.java | 12 ++++++++++-- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java index 49e83aae6..067430e26 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java @@ -21,12 +21,14 @@ import java.util.*; public class StatementGenerator { private JavaClassRegistry reg; + private Map fields; //PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH bekommen private Map localVars; private GenericsRegistry generics; - public StatementGenerator(JavaClassRegistry reg, GenericsRegistry generics, Map localVars){ + public StatementGenerator(JavaClassRegistry reg, GenericsRegistry generics, Map fields, Map localVars){ this.reg = reg; this.generics = generics; + this.fields = fields; this.localVars = localVars; } @@ -238,9 +240,14 @@ public class StatementGenerator { if(localVars.get(expression) != null){ return new LocalVar(expression, localVars.get(expression), offset); }else{ + if(fields.get(expression) != null){//PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH bekommen + return new FieldVar(new This(offset), expression, fields.get(expression), offset); + + } else { + //kann eigentlich nicht vorkommen //Dann Muss es ein Feld sein! return new FieldVar(new This(offset), expression, TypePlaceholder.fresh(offset), offset); - } + }} } return generateFieldVarOrClassname(expression, offset); } @@ -896,7 +903,7 @@ public class StatementGenerator { for(FormalParameter param : params.getFormalparalist()){ lambdaLocals.put(param.getName(), param.getType()); } - StatementGenerator lambdaGenerator = new StatementGenerator(reg, generics, lambdaLocals); + StatementGenerator lambdaGenerator = new StatementGenerator(reg, generics, fields, lambdaLocals); Block block; if(expression.lambdaBody().expression() != null){ diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index 73b0e55f1..b0331a009 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -33,6 +33,7 @@ public class SyntaxTreeGenerator{ private final GenericsRegistry globalGenerics; private String pkgName = ""; Set imports = new HashSet(); + private Map fields = new HashMap<>(); //PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH bekommen List fieldInitializations = new ArrayList<>(); @@ -122,7 +123,7 @@ public class SyntaxTreeGenerator{ private Method convert(int modifiers, Java8Parser.MethodHeaderContext header, Java8Parser.MethodBodyContext body, JavaClassName parentClass, RefType superClass, GenericsRegistry localGenerics) { - StatementGenerator stmtGen = new StatementGenerator(reg, localGenerics, new HashMap<>()); + StatementGenerator stmtGen = new StatementGenerator(reg, localGenerics, fields, new HashMap<>()); String name = header.methodDeclarator().Identifier().getText(); GenericDeclarationList gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), header.getStart()); @@ -346,6 +347,7 @@ public class SyntaxTreeGenerator{ } for(Java8Parser.VariableDeclaratorContext varCtx : fieldDeclarationContext.variableDeclaratorList().variableDeclarator()){ String fieldName = convert(varCtx.variableDeclaratorId()); + fields.put(fieldName, fieldType); if(varCtx.variableInitializer() != null){ initializeField(varCtx, fieldType, generics); } @@ -360,7 +362,7 @@ public class SyntaxTreeGenerator{ // Initialize a field by creating implicit constructor. private void initializeField(Java8Parser.VariableDeclaratorContext ctx, RefTypeOrTPHOrWildcardOrGeneric typeOfField, GenericsRegistry generics){ - StatementGenerator statementGenerator = new StatementGenerator(reg, generics, new HashMap<>()); + StatementGenerator statementGenerator = new StatementGenerator(reg, generics, fields, new HashMap<>()); fieldInitializations.add(statementGenerator.generateFieldAssignment(ctx, typeOfField)); } diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index ea3616eb3..cad3a62f9 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -518,8 +518,16 @@ public class TYPEStmt implements StatementVisitor{ RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset()); */ - methodConstraint.add(new Pair(forMethod.receiver.getType(), assumption.getReceiverType(resolver), - PairOperator.SMALLERDOT)); + + RefTypeOrTPHOrWildcardOrGeneric retType = assumption.getReceiverType(resolver); + /* if (retType instanceof FunN) { + methodConstraint.add(new Pair(forMethod.receiver.getType(), retType, + PairOperator.EQUALSDOT)); + } + else {//RefType */ + methodConstraint.add(new Pair(forMethod.receiver.getType(), retType, + PairOperator.SMALLERDOT)); + //} methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT)); methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info, resolver)); From 9bf273ac1a2c6015c25f798c8788d4c460484dee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Sun, 4 Nov 2018 11:33:32 +0100 Subject: [PATCH 09/14] modified: ../../src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java Unterscheidung zwischen FUNN-Receiver und anderem Receiver wieder geloescht (war nur auskmmentiert) modified: ../../src/de/dhbwstuttgart/typeinference/unify/RuleSet.java Fehler in der Reduce-FUNN-Rege beseitigt --- .../typeinference/typeAlgo/TYPEStmt.java | 8 +------- .../typeinference/unify/RuleSet.java | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index cad3a62f9..330127afc 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -520,14 +520,8 @@ public class TYPEStmt implements StatementVisitor{ */ RefTypeOrTPHOrWildcardOrGeneric retType = assumption.getReceiverType(resolver); - /* if (retType instanceof FunN) { - methodConstraint.add(new Pair(forMethod.receiver.getType(), retType, - PairOperator.EQUALSDOT)); - } - else {//RefType */ - methodConstraint.add(new Pair(forMethod.receiver.getType(), retType, + methodConstraint.add(new Pair(forMethod.receiver.getType(), retType, PairOperator.SMALLERDOT)); - //} methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT)); methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info, resolver)); diff --git a/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java index e438d5003..d4e6b5518 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java @@ -782,10 +782,17 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); Set result = new HashSet(); - - result.add(new UnifyPair(funNLhsType.getTypeParams().get(funNLhsType.getTypeParams().size()-1), funNRhsType.getTypeParams().get(funNRhsType.getTypeParams().size()-1), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair())); - for(int i = 0; i < funNLhsType.getTypeParams().size()-1; i++) { - result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair())); + if (pair.getPairOp() == PairOperator.SMALLERDOT) { + result.add(new UnifyPair(funNLhsType.getTypeParams().get(funNLhsType.getTypeParams().size()-1), funNRhsType.getTypeParams().get(funNRhsType.getTypeParams().size()-1), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair())); + for(int i = 0; i < funNLhsType.getTypeParams().size()-1; i++) { + result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair())); + } + } + else {// pair.getPairOp() == PairOperator.EQUALDOT + result.add(new UnifyPair(funNLhsType.getTypeParams().get(funNLhsType.getTypeParams().size()-1), funNRhsType.getTypeParams().get(funNRhsType.getTypeParams().size()-1), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair())); + for(int i = 0; i < funNLhsType.getTypeParams().size()-1; i++) { + result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), funNLhsType.getTypeParams().get(i), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair())); + } } result.stream().forEach(x -> { UnifyType l = x.getLhsType(); if (l instanceof PlaceholderType) { ((PlaceholderType)l).disableWildcardtable(); } @@ -798,7 +805,7 @@ public class RuleSet implements IRuleSet{ logFile.flush(); } catch (IOException e) { - System.out.println("lofFile-Error"); + System.out.println("logFile-Error"); } return Optional.of(result); } From 26477b60fb6be8e0bc7f112909f57ac49d223883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Sun, 4 Nov 2018 11:55:45 +0100 Subject: [PATCH 10/14] modified: ../bytecode/javFiles/Matrix.jav Typannotationen wieder entfernt --- test/bytecode/javFiles/Matrix.jav | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/bytecode/javFiles/Matrix.jav b/test/bytecode/javFiles/Matrix.jav index 6eae34288..61c601108 100644 --- a/test/bytecode/javFiles/Matrix.jav +++ b/test/bytecode/javFiles/Matrix.jav @@ -18,7 +18,7 @@ public class Matrix extends Vector> { } } - Matrix mul(java.util.Vector> m) { + mul(m) { var ret = new Matrix(); var i = 0; while(i < size()) { From 5ddc9201f7296ff28ca0c1c6b2d790082a122682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Sun, 4 Nov 2018 12:06:09 +0100 Subject: [PATCH 11/14] new file: ../YTest.java new file: Y.jav --- test/bytecode/YTest.java | 52 ++++++++++++++++++++++++++++++++++++ test/bytecode/javFiles/Y.jav | 28 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 test/bytecode/YTest.java create mode 100644 test/bytecode/javFiles/Y.jav diff --git a/test/bytecode/YTest.java b/test/bytecode/YTest.java new file mode 100644 index 000000000..80d37c6ad --- /dev/null +++ b/test/bytecode/YTest.java @@ -0,0 +1,52 @@ +package bytecode; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; + +import org.junit.Test; + +import de.dhbwstuttgart.core.JavaTXCompiler; + +public class YTest { + 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")+"/test/bytecode/javFiles/Y.jav"; + fileToTest = new File(path); + compiler = new JavaTXCompiler(fileToTest); + compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/"); + pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/"; + loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); + classToTest = loader.loadClass("Y"); + /* + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + + Method m = classToTest.getDeclaredMethod("m"); + Class lambda = m.invoke(instanceOfClass).getClass(); + Method apply = lambda.getMethod("apply", Object.class); + + // Damit man auf die Methode zugreifen kann + apply.setAccessible(true); + + Integer i = 77; + + Integer result = (Integer) apply.invoke(m.invoke(instanceOfClass), i); + + assertEquals(77, result); + */ + } + + +} diff --git a/test/bytecode/javFiles/Y.jav b/test/bytecode/javFiles/Y.jav new file mode 100644 index 000000000..3c3e204d0 --- /dev/null +++ b/test/bytecode/javFiles/Y.jav @@ -0,0 +1,28 @@ +import java.lang.Integer; + +class Y { + y; + //factorial; + + Y() { + y = f -> t -> f.apply(y.apply(f)).apply(t); + //factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); }); + } +} + +/* +ergibt Parse-Error +class fac1 { + factorial; + + fac1() { + var y; + y = new Y<>().y; + factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); }); + } + public static void main(String args[]) { + System.out.println(new fac1().factorial.apply(3)); + } + +} +*/ \ No newline at end of file From e6387dca6b80ab339b2647acafaadc93efbc91ea Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Sun, 4 Nov 2018 12:49:11 +0100 Subject: [PATCH 12/14] Bug 116 gefixt --- src/de/dhbwstuttgart/bytecode/BytecodeGen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index 641db6dd0..399abd471 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -374,7 +374,7 @@ public class BytecodeGen implements ASTVisitor { allCons.removeAll(consToRemove); allCons.addAll(result.keySet()); - if(allCons.size()<2) { + if(!allCons.isEmpty() && allCons.size()<2) { if(!result.containsKey(allCons.get(0))) result.put(allCons.get(0), null); From f0ba7c03b5d1637716c6181b4deed03794ac5bbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Mon, 5 Nov 2018 12:01:16 +0100 Subject: [PATCH 13/14] modified: ../../../src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java Bei Int-Literal werden imports beruecksichtigt --- .../typeinference/typeAlgo/TYPEStmt.java | 28 +++++++++++++------ test/bytecode/javFiles/Matrix.jav | 1 + 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index 330127afc..16265b32a 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -4,6 +4,7 @@ import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; +import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.NameGenerator; @@ -18,6 +19,7 @@ import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import java.util.*; import java.util.stream.Collectors; +import java.util.stream.Stream; public class TYPEStmt implements StatementVisitor{ @@ -374,24 +376,34 @@ public class TYPEStmt implements StatementVisitor{ constraintsSet.addUndConstraint(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT)); return; } - if (literal.value instanceof Double) { + if (literal.value instanceof Long) { constraintsSet.addUndConstraint(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT)); return; } if (literal.value instanceof Integer) { //constraintsSet.addUndConstraint(new Pair(literal.getType(),integer, PairOperator.EQUALSDOT)); // /* + HashSet clNames = info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)); Set oderConstraints = new HashSet<>(); Constraint constraint = new Constraint(); constraint.add(new Pair(literal.getType(), integer, PairOperator.EQUALSDOT)); oderConstraints.add(constraint); - constraint = new Constraint(); - constraint.add(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT)); - oderConstraints.add(constraint); - constraint = new Constraint(); - constraint.add(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT)); - oderConstraints.add(constraint); - constraintsSet.addOderConstraint(oderConstraints); + if (clNames.stream().filter(x -> x.toString().equals("java.lang.Double")).findAny().isPresent()) { + constraint = new Constraint(); + constraint.add(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT)); + oderConstraints.add(constraint); + } + if (clNames.stream().filter(x -> x.toString().equals("java.lang.Long")).findAny().isPresent()) { + constraint = new Constraint(); + constraint.add(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT)); + oderConstraints.add(constraint); + } + if (clNames.stream().filter(x -> x.toString().equals("java.lang.Float")).findAny().isPresent()) { + constraint = new Constraint(); + constraint.add(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT)); + oderConstraints.add(constraint); + } + constraintsSet.addOderConstraint(oderConstraints); // */ return; } diff --git a/test/bytecode/javFiles/Matrix.jav b/test/bytecode/javFiles/Matrix.jav index 61c601108..bfe523b6a 100644 --- a/test/bytecode/javFiles/Matrix.jav +++ b/test/bytecode/javFiles/Matrix.jav @@ -1,5 +1,6 @@ import java.util.Vector; import java.lang.Integer; +import java.lang.Float; //import java.lang.Byte; import java.lang.Boolean; From 35696efd1c171ca6b0e6c7f7a8bb2ebc0c7cbc3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Mon, 5 Nov 2018 14:33:44 +0100 Subject: [PATCH 14/14] modified: ../../src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java Alle Basistype bei Literalen hinzugefuegt. --- .../typeinference/typeAlgo/TYPEStmt.java | 22 +++++++++++++++++++ test/bytecode/javFiles/Matrix.jav | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index 16265b32a..609600cd1 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -372,6 +372,18 @@ public class TYPEStmt implements StatementVisitor{ //PL 2018-06-23 Sie haben einen Typ. Der muesste hier eingefuegt werden //wie hier fuer double gezeigt. Im Momment auskommentiert, weil zu wenige Literaltypen //funktionieren + if (literal.value instanceof Short) { + constraintsSet.addUndConstraint(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT)); + return; + } + if (literal.value instanceof Byte) { + constraintsSet.addUndConstraint(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT)); + return; + } + if (literal.value instanceof Float) { + constraintsSet.addUndConstraint(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT)); + return; + } if (literal.value instanceof Double) { constraintsSet.addUndConstraint(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT)); return; @@ -403,6 +415,16 @@ public class TYPEStmt implements StatementVisitor{ constraint.add(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT)); oderConstraints.add(constraint); } + if (clNames.stream().filter(x -> x.toString().equals("java.lang.Short")).findAny().isPresent()) { + constraint = new Constraint(); + constraint.add(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT)); + oderConstraints.add(constraint); + } + if (clNames.stream().filter(x -> x.toString().equals("java.lang.Byte")).findAny().isPresent()) { + constraint = new Constraint(); + constraint.add(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT)); + oderConstraints.add(constraint); + } constraintsSet.addOderConstraint(oderConstraints); // */ return; diff --git a/test/bytecode/javFiles/Matrix.jav b/test/bytecode/javFiles/Matrix.jav index bfe523b6a..48f6eda29 100644 --- a/test/bytecode/javFiles/Matrix.jav +++ b/test/bytecode/javFiles/Matrix.jav @@ -1,6 +1,6 @@ import java.util.Vector; import java.lang.Integer; -import java.lang.Float; +//import java.lang.Float; //import java.lang.Byte; import java.lang.Boolean;