diff --git a/resources/bytecode/javFiles/Matrix.jav b/resources/bytecode/javFiles/Matrix.jav index f8c426b4..b94c0783 100644 --- a/resources/bytecode/javFiles/Matrix.jav +++ b/resources/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; diff --git a/resources/bytecode/javFiles/Scalar.jav b/resources/bytecode/javFiles/Scalar.jav new file mode 100644 index 00000000..381869af --- /dev/null +++ b/resources/bytecode/javFiles/Scalar.jav @@ -0,0 +1,27 @@ +import java.util.Vector; +import java.lang.Integer; +import java.lang.Float; +//import java.lang.Byte; +//import java.lang.Boolean; + +public class Scalar extends Vector { + + Scalar(v) { + Integer i; + i = 0; + while(i < v.size()) { + this.add(v.elementAt(i)); + i=i+1; + } + } + + mul(v) { + var ret = 0; + var i = 0; + while(i < size()) { + ret = ret + this.elementAt(i) * v.elementAt(i); + i = i+1; + } + return ret; + } +} diff --git a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java index fc1b0000..c582fa96 100644 --- a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -69,7 +69,7 @@ public class JavaTXCompiler { //public static JavaTXCompiler INSTANCE; final CompilationEnvironment environment; - Boolean resultmodel = true; + Boolean resultmodel = false; public final Map sourceFiles = new HashMap<>(); Boolean log = false; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll? public volatile UnifyTaskModel usedTasks = new UnifyTaskModel(); diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index 0f1017ed..92b72ec4 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -121,6 +121,7 @@ public class UnifyTypeFactory { } PlaceholderType ntph = new PlaceholderType(tph.getName()); ntph.setVariance(tph.getVariance()); + ntph.setOrCons(tph.getOrCons()); int in = PLACEHOLDERS.indexOf(ntph); if (in == -1) { PLACEHOLDERS.add(ntph); diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java b/src/main/java/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java index 2aaa8068..8452b2c8 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java @@ -24,6 +24,14 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric * wird im Generate Generics Teil nach der Rueckumwandlung nach dem Unify genutzt */ private int variance = 0; + + /* + * Fuer Oder-Constraints: + * orCons = 1: Receiver + * orCons = 0: Argument oder kein Oder-Constraint + * orCons = -1: RetType + */ + private byte orCons = 0; /** @@ -104,4 +112,12 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric public void accept(ResultSetVisitor visitor) { visitor.visit(this); } + + public void setOrCons(byte i) { + orCons = i; + } + + public byte getOrCons() { + return orCons; + } } diff --git a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java index ede06693..195cd785 100644 --- a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java +++ b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java @@ -19,6 +19,7 @@ import de.dhbwstuttgart.typeinference.result.*; import org.objectweb.asm.Attribute; import java.util.*; +import java.util.concurrent.CyclicBarrier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -171,7 +172,6 @@ public class ASTToTargetAST { for (var pair : simplifiedConstraints) { if (pair.left.equals(typeVariable) && typeVariables.contains(pair.right)) { addToPairs(result, new PairTPHsmallerTPH(pair.left, equality.getOrDefault(pair.right, pair.right))); - typeVariables.add(pair.right); } } } @@ -197,7 +197,7 @@ public class ASTToTargetAST { RefTypeOrTPHOrWildcardOrGeneric T2 = superType; if (T2 instanceof TypePlaceholder tph) T2 = equality.getOrDefault(tph, tph); - System.out.println("T1s: " + T1s + "\nT2: " + T2); + System.out.println("T1s: " + T1s + " T2: " + T2); //Ende superType = methodCall.receiverType; @@ -212,7 +212,7 @@ public class ASTToTargetAST { var optMethod = findMethod(owner, methodCall.name, methodCall.getArgumentList()); if (optMethod.isEmpty()) return; var method = optMethod.get(); - var generics = generics(owner, method).javaGenerics(); + var generics = generics(owner, method).txGenerics(); // transitive and var all = transitiveClosure(generics); @@ -227,24 +227,24 @@ public class ASTToTargetAST { // Loop from hell outer: - for (var tph : typeVariables) { - if (typeVariablesOfClass.contains(tph)) continue; + for (var R1 : typeVariables) { + if (typeVariablesOfClass.contains(R1)) continue; for (var generic : all) { if (!(generic.getRight() instanceof TypePlaceholder type)) continue; for (var pair : simplifiedConstraints) { - if (!(pair.left.equals(tph) && pair.right.equals(generic.getLeft()))) + if (!(pair.left.equals(R1) && pair.right.equals(generic.getLeft()))) continue; - for (var tph2 : typeVariables) { + for (var R2 : typeVariables) { for (var pair2 : simplifiedConstraints) { - if (!(pair2.right.equals(tph2) && pair2.left.equals(type))) + if (!(pair2.right.equals(R2) && pair2.left.equals(type))) continue; - if (tph.equals(tph2)) continue; - if (!T1s.contains(tph) || !tph2.equals(T2)) continue; + if (R1.equals(R2)) continue; + if (!T1s.contains(R1) || !R2.equals(T2)) continue; - var newPair = new PairTPHsmallerTPH(tph, tph2); + var newPair = new PairTPHsmallerTPH(R1, R2); newPairs.add(newPair); if (!containsRelation(result, newPair)) @@ -269,7 +269,7 @@ public class ASTToTargetAST { @Override public void visit(Assign assign) { - superType = assign.lefSide.getType(); + superType = assign.rightSide.getType(); assign.rightSide.accept(this); } @@ -522,9 +522,6 @@ public class ASTToTargetAST { super.visit(methodCall); typeVariables.addAll(findTypeVariables(methodCall.getType(), equality)); } - - @Override - public void visit(Assign assign) {} }); } @@ -558,7 +555,7 @@ public class ASTToTargetAST { var referenced = new HashSet(); eliminateCycles(javaResult, equality, referenced); - eliminateInfima(javaResult, equality, referenced); + eliminateInfima(javaResult, equality); var usedTphs = new HashSet(); // For eliminating inner type variables we need to figure out which ones are actually used @@ -576,7 +573,7 @@ public class ASTToTargetAST { { var referenced = new HashSet(); // JavaTX Generics - eliminateInfima(txResult, txEquality, referenced); + eliminateInfima(txResult, txEquality); for (var param : method.getParameterList().getFormalparalist()) { referenced.addAll(findTypeVariables(param.getType(), txEquality)); @@ -637,9 +634,9 @@ public class ASTToTargetAST { var referenced = new HashSet(); eliminateCycles(javaResult, equality, referenced); - eliminateInfima(javaResult, equality, referenced); + eliminateInfima(javaResult, equality); var txReferenced = new HashSet(); - eliminateInfima(txResult, txEquality, txReferenced); + eliminateInfima(txResult, txEquality); eliminateInnerTypeVariablesOfClass(classOrInterface, javaResult, equality, referenced); equalizeTypeVariables(javaResult, equality); @@ -650,19 +647,52 @@ public class ASTToTargetAST { } void equalizeTypeVariables(Set> input, Map equality) { - System.out.println(input); for (var pair : new HashSet<>(input)) { if (pair instanceof PairTPHsmallerTPH ptph) { - System.out.println(pair + " " + ptph.left.getVariance() + " " + ptph.right.getVariance()); - if (ptph.left.getVariance() == 1 && ptph.right.getVariance() == -1) { - addToEquality(equality, ptph.left, ptph.right); - input.remove(ptph); - for (var pair2 : new HashSet<>(simplifiedConstraints)) { - if (pair2.right.equals(ptph.left)) { - simplifiedConstraints.remove(pair2); - simplifiedConstraints.add(new PairTPHsmallerTPH(pair2.left, ptph.right)); + var chain = new ArrayList(); + chain.add(ptph.left); + chain.add(ptph.right); + + outer: while (true) { + var added = false; + for (var pair2 : input) { + if (pair2 instanceof PairTPHsmallerTPH ptph2 && ptph2.left.equals(chain.get(chain.size() - 1))) { + if (chain.contains(ptph2.right)) break outer; + chain.add(ptph2.right); + added = true; } } + if (!added) break; + } + + var variance = chain.get(0).getVariance(); + if (variance != 1) continue; + var index = 0; + for (var tph : chain) { + if (variance == 1 && tph.getVariance() == -1) { + variance = -1; + } + if (variance == -1 && tph.getVariance() == 1) { + break; + } + index++; + } + if (variance == 1) continue; + + var start = chain.get(0); + var prev = start; + for (var i = 1; i < index; i++) { + var cur = chain.get(i); + addToEquality(equality, cur, start); + input.remove(new PairTPHsmallerTPH(prev, chain.get(i))); + for (var pair2 : new HashSet<>(input)) { + // TODO Maybe this would be unnecessary if we were to add the = constraints later on + if (pair2 instanceof PairTPHequalRefTypeOrWildcardType && pair2.getLeft().equals(cur)) { + input.remove(pair2); + input.add(new PairTPHequalRefTypeOrWildcardType(start, pair2.getRight())); + } + } + prev = chain.get(i); } } } @@ -740,6 +770,15 @@ public class ASTToTargetAST { var cycles = findCycles(input); for (var cycle : cycles) { var newTph = TypePlaceholder.fresh(new NullToken()); + var variance = cycle.get(0).getVariance(); + for (var tph : cycle) { + if (tph.getVariance() != variance) { + variance = 0; + break; + } + } + newTph.setVariance(variance); + referenced.add(newTph); addToPairs(input, new PairTPHequalRefTypeOrWildcardType(newTph, OBJECT)); cycle.add(cycle.get(0)); // Make it a complete cycle @@ -753,7 +792,7 @@ public class ASTToTargetAST { } } - void eliminateInfima(Set> input, Map equality, Set referenced) { + void eliminateInfima(Set> input, Map equality) { var foundInfima = false; do { foundInfima = false; @@ -768,7 +807,16 @@ public class ASTToTargetAST { if (infima.size() > 1) { foundInfima = true; var newTph = TypePlaceholder.fresh(new NullToken()); - referenced.add(newTph); + var variance = infima.stream().findFirst().get().right.getVariance(); + for (var pair : infima) { + if (pair.right.getVariance() != variance) { + variance = 0; + break; + } + } + newTph.setVariance(variance); + + //referenced.add(newTph); addToPairs(input, new PairTPHsmallerTPH(left, newTph)); input.removeAll(infima); for (var infimum : infima) { diff --git a/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index 2857d015..acdce189 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -610,8 +610,13 @@ public class TYPEStmt implements StatementVisitor{ //Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ENDE - methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT)); - extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT)); + methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.SMALLERDOT)); + extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.SMALLERDOT)); + + //methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT)); + //extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT)); + + ((TypePlaceholder)forMethod.getType()).setOrCons((byte)-1);//fuer Maximums-Bestimmung Set parameterContraints = generateParameterConstraints(forMethod, assumption, info, resolver); 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 35eee0eb..7e319a42 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java @@ -131,7 +131,11 @@ public class OrderingUnifyPair extends OrderingExtend> { * fuehrt zu Fehlern bei Arrays.sort (contract nicht erfuellt) * @see com.google.common.collect.Ordering#compare(java.lang.Object, java.lang.Object) */ - public int compare (Set left, Set right) { + public int compare (Set leftpara, Set rightpara) { + + Set left = new HashSet<>(leftpara); + Set right = new HashSet<>(rightpara); + /* //pairop = PairOperator.SMALLERDOTWC; List al = new ArrayList<>(); @@ -220,22 +224,26 @@ public class OrderingUnifyPair extends OrderingExtend> { !(y.getRhsType() instanceof PlaceholderType) && x.getPairOp() == PairOperator.EQUALSDOT);}) .collect(Collectors.toCollection(HashSet::new)); + left.removeAll(lefteqOder); Set righteqOder = right.stream() .filter(x -> { UnifyPair y = x.getGroundBasePair(); return (y.getLhsType() instanceof PlaceholderType && !(y.getRhsType() instanceof PlaceholderType) && x.getPairOp() == PairOperator.EQUALSDOT);}) .collect(Collectors.toCollection(HashSet::new)); + right.removeAll(righteqOder); Set lefteqRet = left.stream() .filter(x -> { UnifyPair y = x.getGroundBasePair(); return (y.getRhsType() instanceof PlaceholderType && - x.getPairOp() == PairOperator.EQUALSDOT);}) + ((PlaceholderType)y.getRhsType()).getOrCons() == (byte)-1);}) .collect(Collectors.toCollection(HashSet::new)); + left.removeAll(lefteqRet); Set righteqRet = right.stream() .filter(x -> { UnifyPair y = x.getGroundBasePair(); return (y.getRhsType() instanceof PlaceholderType && - x.getPairOp() == PairOperator.EQUALSDOT);}) + ((PlaceholderType)y.getRhsType()).getOrCons() == (byte)-1);}) .collect(Collectors.toCollection(HashSet::new)); + right.removeAll(righteqRet); Set leftleOder = left.stream() .filter(x -> (x.getPairOp() == PairOperator.SMALLERDOT)) .collect(Collectors.toCollection(HashSet::new)); diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java index 63f3d448..07d85727 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java @@ -59,6 +59,14 @@ public final class PlaceholderType extends UnifyType{ * PL 2018-03-21 */ private int variance = 0; + + /* + * Fuer Oder-Constraints: + * orCons = 1: Receiver + * orCons = 0: Argument oder kein Oder-Constraint + * orCons = -1: RetType + */ + private byte orCons = 0; /** * Creates a new placeholder type with the specified name. @@ -122,6 +130,14 @@ public final class PlaceholderType extends UnifyType{ }} } + public void setOrCons(byte i) { + orCons = i; + } + + public byte getOrCons() { + return orCons; + } + public Boolean isWildcardable() { return wildcardable; } diff --git a/src/test/java/targetast/TestComplete.java b/src/test/java/targetast/TestComplete.java index 1b39618d..34d1370f 100644 --- a/src/test/java/targetast/TestComplete.java +++ b/src/test/java/targetast/TestComplete.java @@ -279,6 +279,32 @@ public class TestComplete { assertEquals(result, instanceOfClass_m3); } + @Test + public void scalarTest() throws Exception { + var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Scalar.jav"); + var scalar = classFiles.get("Scalar"); + + Vector> vv = new Vector<>(); + Vector v1 = new Vector<> (); + v1.addElement(2); + v1.addElement(2); + + var instanceOfClass_s1 = scalar.getDeclaredConstructor(Vector.class).newInstance(v1); + + Vector v2 = new Vector<> (); + v2.addElement(2); + v2.addElement(2); + + var instanceOfClass_s2 = scalar.getDeclaredConstructor(Vector.class).newInstance(v2); + + var mul = scalar.getDeclaredMethod("mul", Vector.class); + var result = mul.invoke(instanceOfClass_s1, instanceOfClass_s2); + System.out.println(instanceOfClass_s1.toString() + " * " + instanceOfClass_s2.toString() + " = " + result.toString()); + + assertEquals(result, 8); + } + + @Test public void mergeTest() throws Exception { var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Merge.jav");