diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index e97b1574c..2ac10fccb 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -6,6 +6,8 @@ import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.syntaxtree.statement.*; @@ -46,7 +48,8 @@ public class BytecodeGen implements ASTVisitor { ClassWriter cw =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS); String type; - + + public static RefTypeOrTPHOrWildcardOrGeneric THISTYPE = null; String className; private boolean isInterface; private List listOfResultSets; @@ -54,10 +57,14 @@ public class BytecodeGen implements ASTVisitor { private SourceFile sf; private String path; + private Optional fieldInitializations; + private int indexOfFirstParam = 0; private String superClass; + private ArrayList tphsClass; + // stores parameter, local vars and the next index on the local variable table, which use for aload_i, astore_i,... HashMap paramsAndLocals = new HashMap<>(); // stores generics and their bounds of class @@ -118,6 +125,7 @@ public class BytecodeGen implements ASTVisitor { int acc = isInterface?classOrInterface.getModifiers()+Opcodes.ACC_ABSTRACT:classOrInterface.getModifiers()+Opcodes.ACC_SUPER; + fieldInitializations = classOrInterface.getfieldInitializations(); // resultSet = listOfResultSets.get(0); boolean isConsWithNoParamsVisited = false; @@ -126,20 +134,44 @@ public class BytecodeGen implements ASTVisitor { superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()); resultSet = rs; tphExtractor.setResultSet(resultSet); + // Nur einmal ausführen!! if(!isVisited) { classOrInterface.accept(tphExtractor); getCommonTPHS(tphExtractor); - + + tphsClass = new ArrayList<>(); + for(TypePlaceholder t : tphExtractor.allTPHS.keySet()) { + 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: * Superclass */ if(classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty() || - classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<")) { - Signature signature = new Signature(classOrInterface, genericsAndBounds,commonPairs); + classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<") + || !tphsClass.isEmpty()) { + Signature signature = new Signature(classOrInterface, genericsAndBounds,commonPairs,tphsClass, consClass); sig = signature.toString(); System.out.println("Signature: => " + sig); } @@ -155,10 +187,12 @@ public class BytecodeGen implements ASTVisitor { } for(Constructor c : classOrInterface.getConstructors()) { - if(!isConsWithNoParamsVisited) +// if(!isConsWithNoParamsVisited) { c.accept(this); - if(!c.getParameterList().iterator().hasNext()) - isConsWithNoParamsVisited = true; +// } + +// if(!c.getParameterList().iterator().hasNext()) +// isConsWithNoParamsVisited = true; } for(Method m : classOrInterface.getMethods()) { @@ -169,6 +203,31 @@ public class BytecodeGen implements ASTVisitor { } + private void removeFromMethod(String name) { + for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) { + ArrayList toRemove = new ArrayList<>(); + for(String tph : m.getTphs()) { + if(tph.equals(name)) { + toRemove.add(tph); + } + } + + if(!toRemove.isEmpty()) { + m.getTphs().removeAll(toRemove); + return; + } + } + + } + + private TypePlaceholder getTPH(String name) { + for(TypePlaceholder tph: tphExtractor.allTPHS.keySet()) { + if(tph.getName().equals(name)) + return tph; + } + throw new NoSuchElementException("TPH "+name +" does not exist"); + } + private void getCommonTPHS(TPHExtractor tphExtractor) { // Gemeinsame TPHs ArrayList cTPHs = new ArrayList<>(); @@ -193,7 +252,7 @@ public class BytecodeGen implements ASTVisitor { field.getParameterList().accept(this); String methParamTypes = field.name+"%%"; - + Iterator itr = field.getParameterList().iterator(); while(itr.hasNext()) { FormalParameter fp = itr.next(); @@ -202,6 +261,7 @@ public class BytecodeGen implements ASTVisitor { } if(methodNameAndParamsT.contains(methParamTypes)) { + System.out.println("ignore - Method: "+field.name +" , paramsType: "+methParamTypes); return; } methodNameAndParamsT.add(methParamTypes); @@ -220,17 +280,22 @@ public class BytecodeGen implements ASTVisitor { } String sig = null; if(hasGen) { - HashMap> constraints = Simplify.simplifyConstraints(field.name, tphExtractor); + HashMap> constraints = Simplify.simplifyConstraints(field.name, tphExtractor,tphsClass); Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,constraints); sig = signature.toString(); } + if(field.getParameterList().iterator().hasNext()) + System.out.println(field.getParameterList().iterator().next().getType().acceptTV(new TypeToDescriptor())); + NormalConstructor constructor = new NormalConstructor(field,genericsAndBounds,hasGen); desc = constructor.accept(new DescriptorToString(resultSet)); + System.out.println("Constructor: " + field.getName() + " Sig: "+ sig + " Desc: " + desc); MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", desc, sig, null); mv.visitCode(); + Block block = fieldInitializations.get().block; BytecodeGenMethod gen = new BytecodeGenMethod(className,superClass,resultSet,field, mv,paramsAndLocals,cw, - genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles, sf,path); - if(!field.getParameterList().iterator().hasNext()) { + genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles, sf,path, block); + if(!field.getParameterList().iterator().hasNext() && !(field.block.statements.get(field.block.statements.size()-1) instanceof ReturnVoid)) { mv.visitInsn(Opcodes.RETURN); } mv.visitMaxs(0, 0); @@ -294,7 +359,7 @@ public class BytecodeGen implements ASTVisitor { System.out.println("ALL CONST: " + tphExtractor.allCons.size()); tphExtractor.allCons.forEach(c->System.out.println(c.toString())); System.out.println("----------------"); - HashMap> constraints = Simplify.simplifyConstraints(method.name, tphExtractor); + HashMap> constraints = Simplify.simplifyConstraints(method.name, tphExtractor, tphsClass); // ArrayList pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons); Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet,constraints); sig = signature.toString(); @@ -375,9 +440,21 @@ public class BytecodeGen implements ASTVisitor { @Override public void visit(Field field) { System.out.println("In Field ---"); + String des = "L"; + if(resultSet.resolveType(field.getType()).resolvedType instanceof TypePlaceholder) { + des += Type.getInternalName(Object.class); + } else { + des += resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToDescriptor()); + } + des +=";"; + System.out.println(des); + String sig = resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToSignature()); + System.out.println(sig); + if(sig.charAt(sig.length()-1) != (";").charAt(0)) { + sig +=";"; + } cw.visitField(field.modifier, field.getName(), - "L"+resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";", - resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToSignature()), + des, sig, null); } diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index df7e85a45..6fc803479 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -75,6 +75,8 @@ public class BytecodeGenMethod implements StatementVisitor { private boolean needDUP = false; + private Block blockFieldInit = null; + private boolean isBlockFieldInitVisited = false; // for tests ** private String fieldName; private String fieldDesc; @@ -85,7 +87,32 @@ public class BytecodeGenMethod implements StatementVisitor { private HashMap classFiles; private ArrayList varsFunInterface = new ArrayList<>();; + // generate bytecode for constructor + public BytecodeGenMethod(String className, String superClass,ResultSet resultSet, Method m, MethodVisitor mv, + HashMap paramsAndLocals, ClassWriter cw, HashMap genericsAndBoundsMethod, + HashMap genericsAndBounds, boolean isInterface, HashMap classFiles, + SourceFile sf,String path, Block block) { + this.className = className; + this.superClass = superClass; + this.resultSet = resultSet; + this.m = m; + this.mv = mv; + this.paramsAndLocals = paramsAndLocals; + this.cw = cw; + this.genericsAndBoundsMethod = genericsAndBoundsMethod; + this.genericsAndBounds = genericsAndBounds; + this.isInterface = isInterface; + this.classFiles = classFiles; + this.sf = sf; + this.path = path; + if(block != null) + this.blockFieldInit = block; + this.m.block.accept(this); + + + } + public BytecodeGenMethod(String className, String superClass,ResultSet resultSet, Method m, MethodVisitor mv, HashMap paramsAndLocals, ClassWriter cw, HashMap genericsAndBoundsMethod, HashMap genericsAndBounds, boolean isInterface, HashMap classFiles, SourceFile sf,String path) { @@ -109,8 +136,9 @@ public class BytecodeGenMethod implements StatementVisitor { } - public BytecodeGenMethod(LambdaExpression lambdaExpression, ResultSet resultSet, MethodVisitor mv, - int indexOfFirstParamLam, boolean isInterface, HashMap classFiles, String path, int lamCounter,SourceFile sf) { + public BytecodeGenMethod(LambdaExpression lambdaExpression, ArrayList usedVars, ResultSet resultSet, MethodVisitor mv, + int indexOfFirstParamLam, boolean isInterface, HashMap classFiles, String path, int lamCounter, SourceFile sf) { + this.resultSet = resultSet; this.mv = mv; this.isInterface = isInterface; @@ -120,6 +148,12 @@ public class BytecodeGenMethod implements StatementVisitor { this.sf = sf; Iterator itr = lambdaExpression.params.iterator(); int i = indexOfFirstParamLam; + + for(String var : usedVars) { + this.paramsAndLocals.put(var, i); + i++; + } + while (itr.hasNext()) { FormalParameter fp = itr.next(); this.paramsAndLocals.put(fp.getName(), i); @@ -154,6 +188,17 @@ public class BytecodeGenMethod implements StatementVisitor { superCall.arglist.accept(this); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, this.superClass, superCall.name, "()V", isInterface); + + if(blockFieldInit!=null && !isBlockFieldInitVisited) { + isBlockFieldInitVisited =true; + //blockFieldInit.accept(this); + for(Statement stmt : blockFieldInit.statements) { + if(stmt instanceof SuperCall) + continue; + + stmt.accept(this); + } + } } // ?? @@ -519,7 +564,7 @@ public class BytecodeGenMethod implements StatementVisitor { @Override public void visit(LambdaExpression lambdaExpression) { this.lamCounter++; - + String typeErasure = "("; Iterator itr = lambdaExpression.params.iterator(); while (itr.hasNext()) { @@ -559,16 +604,31 @@ public class BytecodeGenMethod implements StatementVisitor { this.kindOfLambda = new KindOfLambda(lambdaExpression); if (kindOfLambda.isInstanceCapturingLambda()) { +// if(!kindOfLambda.getArgumentList().contains(BytecodeGen.THISTYPE)) +// kindOfLambda.getArgumentList().add(0, BytecodeGen.THISTYPE); mv.visitVarInsn(Opcodes.ALOAD, 0); + for(String v : kindOfLambda.getUsedVars()) { + mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(v)); + } staticOrSpecial = Opcodes.H_INVOKESPECIAL; indexOfFirstParamLam = 1; } else { staticOrSpecial = Opcodes.H_INVOKESTATIC; staticOrInstance = Opcodes.ACC_STATIC; } - + String newDesc = "("; + int pos = 0; + if(kindOfLambda.isHasThis()) { + pos = 1; + } + + for(int i=pos;i usedVars = kindOfLambda.getUsedVars(); + + new BytecodeGenMethod(lambdaExpression, usedVars,this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface, + classFiles,this.path, lamCounter, sf); - new BytecodeGenMethod(lambdaExpression, this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface, - classFiles,this.path, lamCounter,sf); mvLambdaBody.visitMaxs(0, 0); mvLambdaBody.visitEnd(); cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup", @@ -645,14 +708,23 @@ public class BytecodeGenMethod implements StatementVisitor { @Override public void visit(FieldVar fieldVar) { fieldName = fieldVar.fieldVarName; - fieldDesc = "L" + getResolvedType(fieldVar.getType()) + ";"; + fieldDesc = "L"; + if(resultSet.resolveType(fieldVar.getType()).resolvedType instanceof TypePlaceholder) { + fieldDesc += Type.getInternalName(Object.class); + } else { + fieldDesc += resultSet.resolveType(fieldVar.getType()).resolvedType.acceptTV(new TypeToDescriptor()); + } + fieldDesc +=";"; fieldVar.receiver.accept(this); // test (if) if (!fieldVar.receiver.getClass().equals(StaticClassName.class)) { mv.visitFieldInsn(Opcodes.GETFIELD, getResolvedType(fieldVar.receiver.getType()), fieldName, fieldDesc); } - + + if (isBinaryExp) { + doUnboxing(getResolvedType(fieldVar.getType())); + } // mv.visitFieldInsn(Opcodes.GETSTATIC, // fieldVar.receiver.getType().toString().replace(".", "/"), // fieldVar.fieldVarName, fieldVar.getType().toString()); @@ -1079,6 +1151,10 @@ public class BytecodeGenMethod implements StatementVisitor { @Override public void visit(This aThis) { + + if(BytecodeGen.THISTYPE == null) + BytecodeGen.THISTYPE = aThis.getType(); + mv.visitVarInsn(Opcodes.ALOAD, 0); } @@ -1335,9 +1411,18 @@ public class BytecodeGenMethod implements StatementVisitor { // array slot onto the top of the operand stack. assignLeftSide.field.receiver.accept(this); this.rightSideTemp.accept(this); + String fDesc = "L"; + if(resultSet.resolveType(assignLeftSide.field.getType()).resolvedType instanceof TypePlaceholder) { + fDesc += Type.getInternalName(Object.class); + } else { + fDesc += resultSet.resolveType(assignLeftSide.field.getType()).resolvedType.acceptTV(new TypeToDescriptor()); + } + fDesc +=";"; + + System.out.println("Receiver = " + getResolvedType(assignLeftSide.field.receiver.getType())); mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()), - assignLeftSide.field.fieldVarName, "L"+getResolvedType(assignLeftSide.field.getType())+";"); + assignLeftSide.field.fieldVarName, fDesc); } @Override diff --git a/src/de/dhbwstuttgart/bytecode/descriptor/DescriptorToString.java b/src/de/dhbwstuttgart/bytecode/descriptor/DescriptorToString.java index d92efe5a0..5464aa910 100644 --- a/src/de/dhbwstuttgart/bytecode/descriptor/DescriptorToString.java +++ b/src/de/dhbwstuttgart/bytecode/descriptor/DescriptorToString.java @@ -109,7 +109,7 @@ public class DescriptorToString implements DescriptorVisitor{ desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; } }else { -// System.out.println("Cons has NOT Gens"); +// System.out.println("Cons has NO Gens"); desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; } } diff --git a/src/de/dhbwstuttgart/bytecode/signature/Signature.java b/src/de/dhbwstuttgart/bytecode/signature/Signature.java index 8626cbf9f..995cdf17a 100644 --- a/src/de/dhbwstuttgart/bytecode/signature/Signature.java +++ b/src/de/dhbwstuttgart/bytecode/signature/Signature.java @@ -19,6 +19,7 @@ import de.dhbwstuttgart.syntaxtree.Constructor; import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; +import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; @@ -40,11 +41,16 @@ public class Signature { private ResultSet resultSet; private ArrayList commonPairs; private HashMap> methodConstraints; + private ArrayList tphsClass; + private ArrayList consClass; - public Signature(ClassOrInterface classOrInterface, HashMap genericsAndBounds,ArrayList commonPairs) { + public Signature(ClassOrInterface classOrInterface, HashMap genericsAndBounds, + ArrayList commonPairs, ArrayList tphsClass, ArrayList consClass) { this.classOrInterface = classOrInterface; this.genericsAndBounds = genericsAndBounds; this.commonPairs = commonPairs; + this.tphsClass = tphsClass; + this.consClass = consClass; sw = new SignatureWriter(); createSignatureForClassOrInterface(); } @@ -331,14 +337,16 @@ public class Signature { case "EWC": System.out.println("EWC---Signature"); - SuperWildcardType ewc = (SuperWildcardType) t; + ExtendsWildcardType ewc = (ExtendsWildcardType) t; String esigInner = ewc.getInnerType().acceptTV(new TypeToSignature()); + System.out.println(esigInner); if(ewc.getInnerType() instanceof TypePlaceholder) { sv.visitTypeArgument('+').visitTypeVariable(esigInner.substring(1, esigInner.length())); } else if(ewc.getInnerType() instanceof RefType) { if(esigInner.contains("$$")) { sv.visitTypeArgument('+').visitInterface().visitClassType(esigInner.substring(1,esigInner.length())); }else { +// sv.visitClassType(esigInner.substring(1,esigInner.length())); sv.visitTypeArgument('+').visitClassType(esigInner.substring(1,esigInner.length())); } }else { @@ -364,7 +372,37 @@ public class Signature { GenericTypeVar g = itr.next(); getBoundsOfTypeVar(g,genericsAndBounds); } - if(!commonPairs.isEmpty()) { + + if(!consClass.isEmpty()) { + ArrayList types = new ArrayList<>(); + ArrayList superTypes = new ArrayList<>(); + + for(TPHConstraint cons : consClass) { + types.add(cons.getLeft()); + superTypes.add(cons.getRight()); + } + + for(TPHConstraint cons : consClass) { + String t = cons.getLeft()+"$"; + String bound = cons.getRight()+"$"; + sw.visitFormalTypeParameter(t); + sw.visitClassBound().visitTypeVariable(bound); + genericsAndBounds.put(t, bound); + } + + for(TPHConstraint cons : consClass) { + if(!types.contains(cons.getRight())) { + String t = cons.getRight()+"$"; + String bound = Type.getInternalName(Object.class); + sw.visitFormalTypeParameter(t); + sw.visitClassBound().visitClassType(bound); + genericsAndBounds.put(t, bound); + sw.visitClassBound().visitEnd(); + } + } + + } + /*if(!commonPairs.isEmpty()) { ArrayList types = new ArrayList<>(); ArrayList superTypes = new ArrayList<>(); @@ -392,6 +430,14 @@ public class Signature { } } } + for(TypePlaceholder t : tphsClass) { + String n = t.getName()+"$"; + String bound = Type.getInternalName(Object.class); + sw.visitFormalTypeParameter(n); + sw.visitClassBound().visitClassType(bound); + genericsAndBounds.put(n, bound); + sw.visitClassBound().visitEnd(); + }*/ String sClass = classOrInterface.getSuperClass().acceptTV(new TypeToSignature()); sw.visitSuperclass().visitClassType(sClass.substring(1, sClass.length()-1)); sw.visitEnd(); diff --git a/src/de/dhbwstuttgart/bytecode/utilities/KindOfLambda.java b/src/de/dhbwstuttgart/bytecode/utilities/KindOfLambda.java index 53994d1e6..b897684ab 100644 --- a/src/de/dhbwstuttgart/bytecode/utilities/KindOfLambda.java +++ b/src/de/dhbwstuttgart/bytecode/utilities/KindOfLambda.java @@ -4,22 +4,34 @@ import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.syntaxtree.statement.*; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; +import de.dhbwstuttgart.syntaxtree.FormalParameter; +import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.StatementVisitor; import de.dhbwstuttgart.syntaxtree.statement.Literal; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; public class KindOfLambda implements StatementVisitor{ + private ParameterList params; private boolean isInstanceCapturingLambda = false; private List argumentList = new ArrayList<>(); + private ArrayList usedVars = new ArrayList<>(); + private boolean hasThis = false; + private ArrayList definedLocals = new ArrayList<>(); public KindOfLambda(LambdaExpression lambdaExpression) { + this.params = lambdaExpression.params; lambdaExpression.methodBody.accept(this); } + public ArrayList getUsedVars() { + return usedVars; + } + public boolean isInstanceCapturingLambda() { return this.isInstanceCapturingLambda; } @@ -28,6 +40,10 @@ public class KindOfLambda implements StatementVisitor{ return argumentList; } + public boolean isHasThis() { + return hasThis; + } + @Override public void visit(ArgumentList argumentList) { // TODO Auto-generated method stub @@ -95,14 +111,31 @@ public class KindOfLambda implements StatementVisitor{ @Override public void visit(LocalVar localVar) { - // TODO Auto-generated method stub - + if(!contain(params, localVar.name) && !definedLocals.contains(localVar.name)) { + argumentList.add(localVar.getType()); + if(hasThis) { + usedVars.add(1, localVar.name); + } else { + usedVars.add(0, localVar.name); + } + if(!isInstanceCapturingLambda) + isInstanceCapturingLambda=true; + } + } + + private boolean contain(ParameterList params2, String name) { + Iterator itr = params2.iterator(); + while(itr.hasNext()) { + FormalParameter fp = itr.next(); + if(fp.getName().equals(name)) + return true; + } + return false; } @Override public void visit(LocalVarDecl localVarDecl) { - // TODO Auto-generated method stub - + definedLocals.add(localVarDecl.getName()); } @Override @@ -157,9 +190,13 @@ public class KindOfLambda implements StatementVisitor{ @Override public void visit(This aThis) { + if(!hasThis) { + hasThis = true; + this.argumentList.add(0,aThis.getType()); + } if(!isInstanceCapturingLambda) { this.isInstanceCapturingLambda = true; - this.argumentList.add(aThis.getType()); + } } diff --git a/src/de/dhbwstuttgart/bytecode/utilities/Simplify.java b/src/de/dhbwstuttgart/bytecode/utilities/Simplify.java index c96d21e16..49b1b4f4b 100644 --- a/src/de/dhbwstuttgart/bytecode/utilities/Simplify.java +++ b/src/de/dhbwstuttgart/bytecode/utilities/Simplify.java @@ -8,6 +8,7 @@ import java.util.LinkedList; import org.objectweb.asm.Type; import de.dhbwstuttgart.bytecode.TPHExtractor; +import de.dhbwstuttgart.bytecode.constraint.EqualConstraint; import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation; @@ -15,7 +16,7 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; public class Simplify { - public static HashMap> simplifyConstraints(String name, TPHExtractor tphExtractor) { + 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 @@ -42,7 +43,7 @@ public class Simplify { if(revCon != null) { revCon.setRel(Relation.EQUAL); // the reverse constraint is removed because - // otherwise there is twice the same constraint + // otherwise there is the same constraint twice // (e.g. A A=B and B=A) consToRemove.add(revCon); c.setRel(Relation.EQUAL); @@ -136,9 +137,8 @@ public class Simplify { // put the generated constraint and its equal set into result set result.put(constraint, eq); constraints.clear(); - allTypes.clear(); } - + allTypes.clear(); } } // build an equal set that contains all types @@ -200,6 +200,7 @@ public class Simplify { // 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<>(); @@ -217,9 +218,28 @@ public class Simplify { 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)) @@ -281,17 +301,27 @@ public class Simplify { } if(!containTPH(methodTphs, superTphRes)) { - result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null); + 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); + } + } else { - result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), null); - if(!isTPHInConstraint(result, superTphRes)) - result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null); + 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); + } } } for(String tph : methodTphs) { - if(!isTPHInConstraint(result, tph)) { - result.put(new ExtendsConstraint(tph, Type.getInternalName(Object.class), Relation.EXTENDS), null); + if(!isTPHInConstraint(result, tph) && !isTphInEqualSet(result,tph)) { + HashSet equals = getEqualsTphsFromEqualCons(eqCons,tph); + result.put(new ExtendsConstraint(tph, Type.getInternalName(Object.class), Relation.EXTENDS), equals); } } @@ -315,6 +345,51 @@ public class Simplify { return result; } + private static boolean classTPHSContainsTPH(ArrayList tphsClass, String 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)) + return true; + } + return false; + } + + private static HashSet getEqualsTphsFromEqualCons(ArrayList eqCons, String tph) { + HashSet ee = new HashSet<>(); + for(TPHConstraint c : eqCons) { + if(c.getLeft().equals(tph)) + ee.add(c.getRight()); + 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) { + substituteTPH(allCons, toSubs, 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)) { + String val = subAndSuper.remove(toSubs); + subAndSuper.put(tph, val); + } else { + 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)) diff --git a/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java index 5387e2a11..fdc2770c4 100644 --- a/src/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -1,3 +1,4 @@ +//PL 2018-12-19: typeInferenceOld nach typeInference uebertragen package de.dhbwstuttgart.core; @@ -134,12 +135,21 @@ public class JavaTXCompiler { } //.collect(Collectors.toCollection(ArrayList::new)))) System.out.println(xConsSet); - Set paraTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist() + 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(); @@ -209,6 +219,8 @@ public class JavaTXCompiler { 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) { } return results.stream().map((unifyPairs -> @@ -273,11 +285,21 @@ public class JavaTXCompiler { } logFile.flush(); - Set paraTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist() + 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(); @@ -360,6 +382,8 @@ public class JavaTXCompiler { 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) { } return results.stream().map((unifyPairs -> diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index b0331a009..a945b02aa 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -151,7 +151,7 @@ public class SyntaxTreeGenerator{ block = stmtGen.convert(body.block(),true); } if(parentClass.equals(new JavaClassName(name))){ - return new Constructor(modifiers, name, retType, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations); + return new Constructor(modifiers, name, retType, parameterList, block, gtvDeclarations, header.getStart() /*, fieldInitializations geloescht PL 2018-11-24 */); }else{ return new Method(modifiers, name, retType, parameterList,block, gtvDeclarations, header.getStart()); } @@ -198,14 +198,18 @@ public class SyntaxTreeGenerator{ } List fielddecl = convertFields(ctx.classBody(), generics); //fieldInitializations = generateFieldInitializations(ctx.classBody(), generics); - List methods = convertMethods(ctx.classBody(), name, superClass, generics); + List methodsAndConstructors = convertMethods(ctx.classBody(), name, superClass, generics); + List methods = new ArrayList<>(); List konstruktoren = new ArrayList<>(); - for(int i = 0; i implementedInterfaces = convert(ctx.superinterfaces(), generics); - return new ClassOrInterface(modifiers, name, fielddecl, methods, konstruktoren, genericClassParameters, superClass, + + return new ClassOrInterface(modifiers, name, fielddecl, + Optional.of(this.generatePseudoConstructor(ctx.Identifier().getText(), name, superClass, genericClassParameters, offset)), + methods, konstruktoren, genericClassParameters, superClass, isInterface, implementedInterfaces, offset); } @@ -267,8 +274,16 @@ public class SyntaxTreeGenerator{ RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset); ParameterList params = new ParameterList(new ArrayList<>(), offset); Block block = new Block(new ArrayList<>(), offset); - return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset, fieldInitializations); + return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset /*, fieldInitializations geloescht PL 2018-11-24 */); } + + /* fieldInitializations werden in einem Psedokonstruktor in der abstrakten Syntax gespeichert */ + private Constructor generatePseudoConstructor(String className, JavaClassName parentClass, RefType superClass, GenericDeclarationList classGenerics, Token offset){ + RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset); + ParameterList params = new ParameterList(new ArrayList<>(), offset); + Block block = new Block(new ArrayList<>(fieldInitializations), offset); + return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset /*, fieldInitializations geloescht PL 2018-11-24 */); + } private RefType convert(Java8Parser.SuperclassContext superclass) { if(superclass.classType().classOrInterfaceType() != null){ @@ -441,7 +456,7 @@ public class SyntaxTreeGenerator{ List extendedInterfaces = convert(ctx.extendsInterfaces(), generics); - return new ClassOrInterface(modifiers, name, fields, methods, new ArrayList<>(), + return new ClassOrInterface(modifiers, name, fields, Optional.empty(), methods, new ArrayList<>(), genericParams, superClass, true, extendedInterfaces, ctx.getStart()); } diff --git a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java index d0177ace9..bbd184f0d 100644 --- a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java +++ b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java @@ -3,6 +3,7 @@ package de.dhbwstuttgart.syntaxtree; import de.dhbwstuttgart.core.IItemWithOffset; import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.parser.scope.JavaClassName; +import de.dhbwstuttgart.syntaxtree.statement.Statement; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter; @@ -16,6 +17,7 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Optional; /** * Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces @@ -24,6 +26,7 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{ protected int modifiers; protected JavaClassName name; private List fields = new ArrayList<>(); + private Optional fieldInitializations; //PL 2018-11-24: Noetig, um Bytecode fuer initializators nur einmal zu erzeugen private List methods = new ArrayList<>(); private GenericDeclarationList genericClassParameters; private RefType superClass; @@ -31,13 +34,14 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{ private List implementedInterfaces; private List constructors; - public ClassOrInterface(int modifiers, JavaClassName name, List fielddecl, List methods, List constructors, GenericDeclarationList genericClassParameters, + public ClassOrInterface(int modifiers, JavaClassName name, List fielddecl, Optional fieldInitializations, List methods, List constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List implementedInterfaces, Token offset){ super(offset); if(isInterface && !Modifier.isInterface(modifiers))modifiers += Modifier.INTERFACE; this.modifiers = modifiers; this.name = name; this.fields = fielddecl; + this.fieldInitializations= fieldInitializations; this.genericClassParameters = genericClassParameters; this.superClass = superClass; this.isInterface = isInterface; @@ -59,6 +63,11 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{ public List getFieldDecl(){ return this.fields; } + + public Optional getfieldInitializations(){ + return this.fieldInitializations; + } + public List getMethods(){ return this.methods; } diff --git a/src/de/dhbwstuttgart/syntaxtree/Constructor.java b/src/de/dhbwstuttgart/syntaxtree/Constructor.java index 79db5ced9..8be687f8e 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Constructor.java +++ b/src/de/dhbwstuttgart/syntaxtree/Constructor.java @@ -15,8 +15,8 @@ public class Constructor extends Method { //TODO: Constructor braucht ein super-Statement public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList parameterList, Block codeInsideConstructor, - GenericDeclarationList gtvDeclarations, Token offset, List fieldInitializations) { - super(modifier, name, returnType, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations), gtvDeclarations, offset); + GenericDeclarationList gtvDeclarations, Token offset /*, List fieldInitializations geloescht PL 2018-11-24 */) { + super(modifier, name, returnType, parameterList, /*codeInsideConstructor,*/ prepareBlock(codeInsideConstructor ) /*,fieldInitializations )geloescht PL 2018-11-24 )*/, gtvDeclarations, offset); } @@ -25,10 +25,10 @@ public class Constructor extends Method { * welche die Felder der zugehörigen Klasse dieses * Konstruktor initialisieren */ - protected static Block prepareBlock(Block constructorBlock, List fieldInitializations){ + protected static Block prepareBlock(Block constructorBlock /*, List fieldInitializations new ArrayList<>() geloescht PL 2018-11-24 */){ List statements = constructorBlock.getStatements(); statements.add(0, new SuperCall(constructorBlock.getOffset())); - statements.addAll(fieldInitializations); + /* statements.addAll(fieldInitializations); geloescht PL 2018-11-24 */ return new Block(statements, constructorBlock.getOffset()); } diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java index d92d0b9a9..2fb32dbee 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java @@ -4,6 +4,7 @@ import java.lang.reflect.*; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.NullToken; @@ -65,7 +66,7 @@ public class ASTFactory { Token offset = new NullToken(); //Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde - return new ClassOrInterface(modifier, name, felder, methoden, konstruktoren, genericDeclarationList, superClass,isInterface, implementedInterfaces, offset); + return new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */,methoden, konstruktoren, genericDeclarationList, superClass,isInterface, implementedInterfaces, offset); } private static Field createField(java.lang.reflect.Field field, JavaClassName jreClass) { @@ -98,7 +99,7 @@ public class ASTFactory { return null; } - return new de.dhbwstuttgart.syntaxtree.Constructor(modifier, name,returnType, parameterList, block, gtvDeclarations, offset, new ArrayList<>()); + return new de.dhbwstuttgart.syntaxtree.Constructor(modifier, name,returnType, parameterList, block, gtvDeclarations, offset /*, new ArrayList<>() geloescht PL 2018-11-24 */); } public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){ diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java b/src/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java index 0c8220f16..6067851ee 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java @@ -17,10 +17,11 @@ import org.antlr.v4.runtime.Token; import java.util.ArrayList; import java.util.List; +import java.util.Optional; public class FunNClass extends ClassOrInterface { public FunNClass(List funNParams) { - super(0, new JavaClassName("Fun"+(funNParams.size())), new ArrayList<>(), + super(0, new JavaClassName("Fun"+(funNParams.size())), new ArrayList<>(), Optional.empty() /* eingefuegt PL 2018-11-24 */, createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams), ASTFactory.createObjectType(), true, new ArrayList<>(), new NullToken()); diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java index 6a4410505..246c36912 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java @@ -38,6 +38,9 @@ public class TYPE { for(Constructor m : cl.getConstructors()){ ret.addAll(getConstraintsConstructor(m,info, cl)); } + if (cl.getfieldInitializations().isPresent()) { + ret.addAll(getConstraintsConstructor(cl.getfieldInitializations().get(), info, cl)); + } return ret; } /* @@ -61,6 +64,7 @@ public class TYPE { return new TypeInferenceInformation(classes); } */ + private ConstraintSet getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) { if(m.block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m); diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index e06669505..4fd14fbc8 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -1,3 +1,4 @@ +//PL 2018-12-19: Merge chekcen package de.dhbwstuttgart.typeinference.typeAlgo; import de.dhbwstuttgart.exceptions.NotImplementedException; @@ -261,7 +262,7 @@ public class TYPEStmt implements StatementVisitor{ numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.getType(), integer, PairOperator.SMALLERDOT)); + numeric.add(new Pair(integer, binary.getType(), PairOperator.SMALLERDOT)); numericAdditionOrStringConcatenation.add(numeric); } //PL eingefuegt 2018-07-17 @@ -269,7 +270,7 @@ public class TYPEStmt implements StatementVisitor{ numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.getType(), longg, PairOperator.SMALLERDOT)); + numeric.add(new Pair(longg, binary.getType(), PairOperator.SMALLERDOT)); numericAdditionOrStringConcatenation.add(numeric); } //PL eingefuegt 2018-07-17 @@ -277,7 +278,7 @@ public class TYPEStmt implements StatementVisitor{ numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.getType(), floatt, PairOperator.SMALLERDOT)); + numeric.add(new Pair(floatt, binary.getType(), PairOperator.SMALLERDOT)); numericAdditionOrStringConcatenation.add(numeric); } //PL eingefuegt 2018-07-17 @@ -285,7 +286,7 @@ public class TYPEStmt implements StatementVisitor{ numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.getType(), doublee, PairOperator.SMALLERDOT)); + numeric.add(new Pair(doublee, binary.getType(), PairOperator.SMALLERDOT)); numericAdditionOrStringConcatenation.add(numeric); } /* PL auskommentiert Anfang 2018-07-17 @@ -305,7 +306,7 @@ public class TYPEStmt implements StatementVisitor{ Constraint stringConcat = new Constraint<>(); stringConcat.add(new Pair(binary.lexpr.getType(), string, PairOperator.EQUALSDOT)); stringConcat.add(new Pair(binary.rexpr.getType(), string, PairOperator.EQUALSDOT)); - stringConcat.add(new Pair(binary.getType(), string, PairOperator.EQUALSDOT)); + stringConcat.add(new Pair(string, binary.getType(), PairOperator.EQUALSDOT)); numericAdditionOrStringConcatenation.add(stringConcat); } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java b/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java index fbf354d0e..306552b33 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java +++ b/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java @@ -1,3 +1,4 @@ +//PL 2018-12-19: Merge checken package de.dhbwstuttgart.typeinference.unify; import java.util.ArrayList; @@ -748,8 +749,9 @@ public class TypeUnifyTask extends RecursiveTask>> { if (nextSetasList.iterator().next().stream().filter(x -> x.getLhsType().getName().equals("D")).findFirst().isPresent() && nextSetasList.size()>1) System.out.print(""); writeLog("nextSetasList: " + nextSetasList.toString()); + Set a = null; while (nextSetasList.size() > 0) { //(nextSetasList.size() != 0) { - Set a = null; + Set a_last = a; if (variance == 1) { a = oup.max(nextSetasList.iterator()); nextSetasList.remove(a); @@ -800,9 +802,59 @@ public class TypeUnifyTask extends RecursiveTask>> { if ((isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result)) || (!isUndefinedPairSetSet(res) && !isUndefinedPairSetSet(result)) || result.isEmpty()) { + + if ((!result.isEmpty() && !res.isEmpty() && !isUndefinedPairSetSet(res) && !isUndefinedPairSetSet(result)) //korrekte Loesungen aus und-constraints + && (a.stream().map(x-> (x.getBasePair() != null)).reduce(true, (x, y) -> (x && y)))) //bei oder-Constraints nicht ausfuehren + { + + //Alle Variablen bestimmen die nicht hinzugefügt wurden in a + List vars_a = a.stream().filter(x -> (x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName()) + ||x.getLhsType().getName().equals(x.getBasePair().getRhsType().getName()))).map(y -> (PlaceholderType)y.getLhsType()).collect(Collectors.toCollection(ArrayList::new)); + Set fstElemRes = res.iterator().next(); + Set compRes = fstElemRes.stream().filter(x -> vars_a.contains(((PlaceholderType)x.getLhsType()))).collect(Collectors.toCollection(HashSet::new)); + + //Alle Variablen bestimmen die nicht hinzugefügt wurden in a_last + List varsLast_a = a_last.stream().filter(x -> (x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName()) + ||x.getLhsType().getName().equals(x.getBasePair().getRhsType().getName()))).map(y -> (PlaceholderType)y.getLhsType()).collect(Collectors.toCollection(ArrayList::new)); + //erstes Element genügt, da vars immer auf die gleichen Elemente zugeordnet werden muessen + Set fstElemResult = result.iterator().next(); + Set compResult = fstElemResult.stream().filter(x -> varsLast_a.contains(((PlaceholderType)x.getLhsType()))).collect(Collectors.toCollection(HashSet::new));; + + if (variance == 1) { + int resOfCompare = oup.compare(compResult, compRes); + if (resOfCompare == -1) { + writeLog("Geloescht result: " + result); + result = res; + } else { + if (resOfCompare == 0) { + result.addAll(res); + } //else { + if (resOfCompare == 1) { + writeLog("Geloescht res: " + res); + //result = result; + }}} + else { if (variance == -1) { + int resOfCompare = oup.compare(compResult, compRes); + if (resOfCompare == 1) { + writeLog("Geloescht result: " + result); + result = res; + } else { + if (resOfCompare == 0) { + result.addAll(res); + } else { + if (resOfCompare == -1) { + writeLog("Geloescht res: " + res); + //result = result; + }}}} + else { if (variance == 0) { + result.addAll(res); + }}} //alle Fehlerfaelle und alle korrekten Ergebnis jeweils adden - result.addAll(res); - } + } + else { + result.addAll(res); + } + } //else { //wenn Korrekte Ergebnisse da und Feherfälle dazukommen Fehlerfälle ignorieren // if (isUndefinedPairSetSet(res) && !isUndefinedPairSetSet(result)) { @@ -820,7 +872,7 @@ public class TypeUnifyTask extends RecursiveTask>> { if (!result.isEmpty() && !isUndefinedPairSetSet(res)) { if (nextSetasList.iterator().hasNext() && nextSetasList.iterator().next().stream().filter(x -> x.getLhsType().getName().equals("B")).findFirst().isPresent() && nextSetasList.size()>1) System.out.print(""); - Iterator> nextSetasListIt = new ArrayList>(nextSetasList).iterator(); + Iterator> nextSetasListIt = new ArrayList>(nextSetasList).iterator(); if (variance == 1) { System.out.println(""); while (nextSetasListIt.hasNext()) { @@ -1492,7 +1544,7 @@ public class TypeUnifyTask extends RecursiveTask>> { Set resultPrime = new HashSet<>(); for(int i = 0; !allGen && i < theta.getTypeParams().size(); i++) { - if(freshTphs.size()-1 < i) + if(freshTphs.size()-1 < i)//IST DAS RICHTIG??? PL 2018-12-12 freshTphs.add(PlaceholderType.freshPlaceholder()); resultPrime.add(new UnifyPair(freshTphs.get(i), theta.getTypeParams().get(i), PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair)); } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 5eef03089..4aa769e55 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -5,6 +5,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; +import java.util.List; import java.util.Optional; import java.util.Set; import java.util.function.BiFunction; @@ -26,7 +27,8 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; * The finite closure for the type unification * @author Florian Steurer */ -public class FiniteClosure extends Ordering implements IFiniteClosure { +public class FiniteClosure //extends Ordering //entfernt PL 2018-12-11 +implements IFiniteClosure { /** * A map that maps every type to the node in the inheritance graph that contains that type. @@ -561,14 +563,53 @@ public class FiniteClosure extends Ordering implements IFiniteClosure return this.inheritanceGraph.toString(); } + /* entfernt PL 2018-12-11 public int compare (UnifyType left, UnifyType right) { return compare(left, right, PairOperator.SMALLERDOT); } + */ public int compare (UnifyType left, UnifyType right, PairOperator pairop) { if ((left instanceof ExtendsType && right instanceof ReferenceType) || (right instanceof ExtendsType && left instanceof ReferenceType)) System.out.println(""); + /* + List al = new ArrayList<>(); + PlaceholderType xx =new PlaceholderType("xx"); + al.add(xx); + left = new ExtendsType(new ReferenceType("Vector", new TypeParams(al))); + right = new ReferenceType("Vector", new TypeParams(new ArrayList<>(al))); + */ + /* + List al = new ArrayList<>(); + PlaceholderType xx =new PlaceholderType("xx"); + al.add(xx); + left = new ExtendsType(xx); + right = xx; + */ + /* + List al = new ArrayList<>(); + PlaceholderType xx =new PlaceholderType("xx"); + PlaceholderType yy =new PlaceholderType("yy"); + al.add(xx); + left = yy; + right = new ExtendsType(xx); + */ + //Die Faelle abfangen, bei den Variablen verglichen werden PL 2018-12-11 + UnifyType ex; + if (left instanceof PlaceholderType) { + if ((right instanceof WildcardType) + && ((ex = ((WildcardType)right).wildcardedType) instanceof PlaceholderType) + && ((PlaceholderType)left).getName().equals(((PlaceholderType)ex).getName())) {// a <.? ? extends a oder a <.? ? super a + return -1; + } + else { + return 0; + } + } + if ((right instanceof PlaceholderType) && (left instanceof WildcardType)) { + return 0; + } UnifyPair up = new UnifyPair(left, right, pairop); TypeUnifyTask unifyTask = new TypeUnifyTask(); HashSet hs = new HashSet<>(); diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java b/src/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java index 8cebdd8a9..c655e6fd2 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java @@ -151,7 +151,7 @@ public class OrderingUnifyPair extends Ordering> { System.out.print(""); //Set varsleft = lefteq.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new)); //Set varsright = righteq.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new)); - //filtern des Paares a = Theta, das durch a <. Thata' generiert wurde (nur im Fall 1 relevant) + //filtern des Paares a = Theta, das durch a <. Thata' generiert wurde (nur im Fall 1 relevant) andere Substitutioen werden rausgefiltert lefteq.removeIf(x -> !(x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName()) ||x.getLhsType().getName().equals(x.getBasePair().getRhsType().getName())));//removeIf(x -> !varsright.contains(x.getLhsType())); righteq.removeIf(x -> !(x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName()) diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java index ef41de65d..012099987 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java @@ -1,5 +1,7 @@ package de.dhbwstuttgart.typeinference.unify.model; +import java.io.File; +import java.io.FileWriter; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -21,7 +23,7 @@ public final class PlaceholderType extends UnifyType{ * Static list containing the names of all existing placeholders. * Used for generating fresh placeholders. */ - protected static final HashSet EXISTING_PLACEHOLDERS = new HashSet(); + public static final ArrayList EXISTING_PLACEHOLDERS = new ArrayList(); /** * Prefix of auto-generated placeholder names. @@ -81,11 +83,12 @@ public final class PlaceholderType extends UnifyType{ * A user could later instantiate a type using the same name that is equivalent to this type. * @return A fresh placeholder type. */ - public static PlaceholderType freshPlaceholder() { + public synchronized static PlaceholderType freshPlaceholder() { String name = nextName + (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z' // Add random chars while the name is in use. - while(EXISTING_PLACEHOLDERS.contains(name)); + while(EXISTING_PLACEHOLDERS.contains(name)) { name += (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z' + } return new PlaceholderType(name, true); } diff --git a/test/bytecode/FieldTph.java b/test/bytecode/FieldTph.java new file mode 100644 index 000000000..3edb43d13 --- /dev/null +++ b/test/bytecode/FieldTph.java @@ -0,0 +1,43 @@ +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")+"/test/bytecode/javFiles/FieldTph.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("FieldTph"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + } + + @Test + public void test() { + Field[] fields = classToTest.getFields(); + assertEquals(1, fields.length); + } + +} diff --git a/test/bytecode/FieldTph2Test.java b/test/bytecode/FieldTph2Test.java new file mode 100644 index 000000000..2ed19d330 --- /dev/null +++ b/test/bytecode/FieldTph2Test.java @@ -0,0 +1,52 @@ +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 FieldTph2Test { + + 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/FieldTph2.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("FieldTph2"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + } + + @Test + public void test() throws Exception { + Field a = classToTest.getDeclaredField("a"); + a.setAccessible(true); + + Method m2 = classToTest.getDeclaredMethod("m2", Object.class); + m2.invoke(instanceOfClass, 1); + + Method m = classToTest.getDeclaredMethod("m", Object.class); + Object result = m.invoke(instanceOfClass, 1); + + assertEquals(1,result); + } + +} diff --git a/test/bytecode/LambdaCapturetest.java b/test/bytecode/LambdaCapturetest.java new file mode 100644 index 000000000..438c2315c --- /dev/null +++ b/test/bytecode/LambdaCapturetest.java @@ -0,0 +1,43 @@ +/** + * + */ +package bytecode; + +import static org.junit.Assert.*; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; + +import org.junit.BeforeClass; +import org.junit.Test; + +import de.dhbwstuttgart.core.JavaTXCompiler; + +/** + * @author fayez + * + */ +public class LambdaCapturetest { + 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/LambdaCapture.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("LambdaCapture"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + } + +} diff --git a/test/bytecode/YTest.java b/test/bytecode/YTest.java index 80d37c6ad..1c4f13a64 100644 --- a/test/bytecode/YTest.java +++ b/test/bytecode/YTest.java @@ -25,11 +25,11 @@ public class YTest { 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"); +// 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(); diff --git a/test/bytecode/javFiles/FieldTph.jav b/test/bytecode/javFiles/FieldTph.jav new file mode 100644 index 000000000..fc74e5396 --- /dev/null +++ b/test/bytecode/javFiles/FieldTph.jav @@ -0,0 +1,4 @@ +public class FieldTph { + a; + +} \ No newline at end of file diff --git a/test/bytecode/javFiles/FieldTph2.jav b/test/bytecode/javFiles/FieldTph2.jav new file mode 100644 index 000000000..7d60b683a --- /dev/null +++ b/test/bytecode/javFiles/FieldTph2.jav @@ -0,0 +1,12 @@ +public class FieldTph2 { + a; + + m(b){ + b = a; + return b; + } + + m2(c){ + a = c; + } +} \ No newline at end of file diff --git a/test/bytecode/javFiles/LambdaCapture.jav b/test/bytecode/javFiles/LambdaCapture.jav new file mode 100644 index 000000000..ab1751f4d --- /dev/null +++ b/test/bytecode/javFiles/LambdaCapture.jav @@ -0,0 +1,12 @@ +import java.lang.Integer; +public class LambdaCapture { + Integer i = 8; + f; + public LambdaCapture(){ + Integer w = 7; + f = j ->{ + return w+i;}; + + } + +} \ No newline at end of file diff --git a/test/bytecode/javFiles/OL.jav b/test/bytecode/javFiles/OL.jav index 68650428e..700e50f0a 100644 --- a/test/bytecode/javFiles/OL.jav +++ b/test/bytecode/javFiles/OL.jav @@ -9,7 +9,7 @@ public class OL { m(x) { return x + x; } } - + public class OLMain { @@ -20,4 +20,3 @@ public class OLMain { return ol.m(x); } } - diff --git a/test/bytecode/simplifyalgo/CycleTest.java b/test/bytecode/simplifyalgo/CycleTest.java index 88697e6d9..f847eff47 100644 --- a/test/bytecode/simplifyalgo/CycleTest.java +++ b/test/bytecode/simplifyalgo/CycleTest.java @@ -5,6 +5,7 @@ package bytecode.simplifyalgo; import static org.junit.Assert.*; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -68,7 +69,7 @@ public class CycleTest { TPHConstraint k = new ExtendsConstraint("A", Type.getInternalName(Object.class), Relation.EXTENDS); result.put(k, equals); - HashMap> sim = Simplify.simplifyConstraints(methName, tphExtractor); + HashMap> sim = Simplify.simplifyConstraints(methName, tphExtractor,new ArrayList<>()); boolean areEquals = SimpleCycle.areMapsEqual(result, sim); assertTrue(areEquals); } diff --git a/test/bytecode/simplifyalgo/SameLeftSide.java b/test/bytecode/simplifyalgo/SameLeftSide.java index b5c4e875f..69d50c63b 100644 --- a/test/bytecode/simplifyalgo/SameLeftSide.java +++ b/test/bytecode/simplifyalgo/SameLeftSide.java @@ -2,6 +2,7 @@ package bytecode.simplifyalgo; import static org.junit.Assert.*; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -70,11 +71,13 @@ public class SameLeftSide { TPHConstraint d = new ExtendsConstraint("D", Type.getInternalName(Object.class), Relation.EXTENDS); TPHConstraint a = new ExtendsConstraint("A", "D", Relation.EXTENDS); TPHConstraint b = new ExtendsConstraint("B", "D", Relation.EXTENDS); - result.put(d, null); - result.put(a, null); - result.put(b, null); + result.put(d, new HashSet<>()); + result.put(a, new HashSet<>()); + HashSet hs = new HashSet<>(); - HashMap> sim = Simplify.simplifyConstraints(methName, tphExtractor); + result.put(b, hs); + + HashMap> sim = Simplify.simplifyConstraints(methName, tphExtractor,new ArrayList<>()); boolean areEquals = SimpleCycle.areMapsEqual(result, sim); assertTrue(areEquals); } @@ -86,10 +89,12 @@ public class SameLeftSide { TPHConstraint e = new ExtendsConstraint("E", Type.getInternalName(Object.class), Relation.EXTENDS); TPHConstraint c = new ExtendsConstraint("C", "E", Relation.EXTENDS); - result.put(e, null); - result.put(c, null); + result.put(e, new HashSet<>()); + HashSet hs = new HashSet<>(); + hs.add("B"); + result.put(c, hs); - HashMap> sim = Simplify.simplifyConstraints(methName2, tphExtractor); + HashMap> sim = Simplify.simplifyConstraints(methName2, tphExtractor,new ArrayList<>()); boolean areEquals = SimpleCycle.areMapsEqual(result, sim); assertTrue(areEquals); } diff --git a/test/bytecode/simplifyalgo/SimpleCycle.java b/test/bytecode/simplifyalgo/SimpleCycle.java index 636eb026d..545b0514e 100644 --- a/test/bytecode/simplifyalgo/SimpleCycle.java +++ b/test/bytecode/simplifyalgo/SimpleCycle.java @@ -2,6 +2,7 @@ package bytecode.simplifyalgo; import static org.junit.Assert.*; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -45,7 +46,7 @@ public class SimpleCycle { TPHConstraint k = new ExtendsConstraint("B", Type.getInternalName(Object.class), Relation.EXTENDS); result.put(k, equals); - HashMap> sim = Simplify.simplifyConstraints(methName, tphExtractor); + HashMap> sim = Simplify.simplifyConstraints(methName, tphExtractor,new ArrayList<>()); boolean areEquals = areMapsEqual(result, sim); assertTrue(areEquals); }