diff --git a/src/de/dhbwstuttgart/.DS_Store b/src/de/dhbwstuttgart/.DS_Store index f20299e87..aa8a1074b 100644 Binary files a/src/de/dhbwstuttgart/.DS_Store and b/src/de/dhbwstuttgart/.DS_Store differ diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index 0dd573749..a3103657f 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -121,7 +121,7 @@ public class BytecodeGen implements ASTVisitor { // Nur einmal ausführen!! if(!isVisited) { classOrInterface.accept(tphExtractor); - + getCommonTPHS(tphExtractor); String sig = null; @@ -275,6 +275,11 @@ public class BytecodeGen implements ASTVisitor { } private ArrayList simplifyPairs(String methodName, ArrayList allPairs) { + allPairs.forEach(p->System.out.print(p.TA1 + " < "+ p.TA2+ " ; ")); + + if(allPairs.size() < 2) + return allPairs; + ArrayList simplifiedPairs = new ArrayList<>(); MethodAndTPH method; @@ -320,22 +325,41 @@ public class BytecodeGen implements ASTVisitor { numOfVisitedPairs++; } - // TODO: teste noch den Fall X < Y und Y nicht in TPHS der Methode - // Dann hat man nach der While-Schleife X < Y - // Y muss durch Object ersetzt. - // Subtype TypePlaceholder subTphRes = tphsInRel.get(0); // Die größte Supertype TypePlaceholder superTphRes = tphsInRel.get(tphsInRel.size()-1); + + while(subAndSuperTph.containsValue(subTphRes)) { + for(TypePlaceholder tph : subAndSuperTph.keySet()) { + if(methodTphs.contains(tph) && subAndSuperTph.get(tph).equals(subTphRes)) { + subTphRes = tph; + break; + } + } + if(subTphRes.equals(tphsInRel.get(0))) { + break; + } + tphsInRel.put(0, subTphRes); + numOfVisitedPairs++; + } + + subTphRes = tphsInRel.get(0); + int i = 2; while(!methodTphs.contains(superTphRes) && (tphsInRel.size()-i) >0) { superTphRes = tphsInRel.get(tphsInRel.size()-i); i++; } + // teste noch den Fall X < Y und Y nicht in TPHS der Methode + // Dann hat man nach der While-Schleife X < Y + // Y muss durch Object ersetzt. - GenericInsertPair sPair = new GenericInsertPair(subTphRes, superTphRes); - simplifiedPairs.add(sPair); + // Zweite Operand für die Fälle wie in Lambda.jav (Paramtrisierte Typen) + if(methodTphs.contains(superTphRes) || !tphExtractor.allTPHS.containsKey(superTphRes)) { + GenericInsertPair sPair = new GenericInsertPair(subTphRes, superTphRes); + simplifiedPairs.add(sPair); + } } return simplifiedPairs; } @@ -599,7 +623,6 @@ public class BytecodeGen implements ASTVisitor { methodAndTph.getTphs().add(resolvedTPH); allTPHS.put(resolvedTPH,inMethod); - ResolvedType rst = resultSet.resolveType(tph); resultSet.resolveType(tph).additionalGenerics.forEach(ag ->{ if(ag.contains(resolvedTPH)&&ag.TA1.equals(resolvedTPH)&&!contains(allPairs,ag)) { if(inMethod) @@ -625,6 +648,7 @@ public class BytecodeGen implements ASTVisitor { inMethod = false; ListOfMethodsAndTph.add(methodAndTph); } + } } diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index 9d03979fc..6b6cab175 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -639,19 +639,32 @@ public class BytecodeGenMethod implements StatementVisitor { public void visit(MethodCall methodCall) { //ClassLoader.getSystemClassLoader().loadClass(className).getMethod(name, parameterTypes) + String receiverName = getResolvedType(methodCall.receiver.getType()); + System.out.println("Methods of " + receiverName + " "); + ClassLoader cl = ClassLoader.getSystemClassLoader(); + try { + java.lang.reflect.Method[] methods = cl.loadClass("java.util.Vector").getMethods(); + System.out.println("Methods of " + receiverName + " "); + for(java.lang.reflect.Method m : methods) { + System.out.println(m.getName() + " " + m.toGenericString()+ " ==> "); + } + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } System.out.println("Methodcall type : " + resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor())); methodCall.receiver.accept(this); methodCall.arglist.accept(this); MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(), - genericsAndBoundsMethod, genericsAndBounds); + receiverName, genericsAndBoundsMethod, genericsAndBounds); String mDesc = method.accept(new DescriptorToString(resultSet)); System.out.println("Methodcall Desc : " + mDesc); // is methodCall.receiver functional Interface)? if (varsFunInterface.contains(methodCall.receiver.getType())) { mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()), methodCall.name, - mDesc, false); + mDesc, true); } else { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()), methodCall.name, mDesc, isInterface); diff --git a/src/de/dhbwstuttgart/bytecode/descriptor/DescriptorToString.java b/src/de/dhbwstuttgart/bytecode/descriptor/DescriptorToString.java index b22109c16..d92efe5a0 100644 --- a/src/de/dhbwstuttgart/bytecode/descriptor/DescriptorToString.java +++ b/src/de/dhbwstuttgart/bytecode/descriptor/DescriptorToString.java @@ -123,9 +123,21 @@ public class DescriptorToString implements DescriptorVisitor{ Iterator itr = lambdaExpression.getParams().iterator(); while(itr.hasNext()) { FormalParameter fp = itr.next(); - desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()) + ";"; + String d = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()); + if(d.substring(0, 4).equals("TPH ") ||d.contains("<")) { + desc += "L"+Type.getInternalName(Object.class)+ ";"; + }else { + desc = desc + "L"+ d + ";"; + } + } + + String retType = resultSet.resolveType(lambdaExpression.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor()); + + if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<")){ + desc += ")L"+Type.getInternalName(Object.class)+ ";"; + }else { + desc = desc + ")"+"L"+retType+";"; } - desc = addReturnType(desc, lambdaExpression.getReturnType(), resultSet); return desc; } @@ -135,9 +147,22 @@ public class DescriptorToString implements DescriptorVisitor{ Iterator itr = samMethod.getArgumentList().iterator(); while(itr.hasNext()) { RefTypeOrTPHOrWildcardOrGeneric rt = itr.next(); - desc = desc + "L"+resultSet.resolveType(rt).resolvedType.acceptTV(new TypeToDescriptor())+";"; + String d = resultSet.resolveType(rt).resolvedType.acceptTV(new TypeToDescriptor()); + + if(d.substring(0, 4).equals("TPH ") ||d.contains("<")) { + desc += "L"+Type.getInternalName(Object.class)+ ";"; + }else { + desc += "L"+ d + ";"; + + } + } + String retType = resultSet.resolveType(samMethod.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor()); + + if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<")){ + desc += ")L"+Type.getInternalName(Object.class)+ ";"; + }else { + desc = desc + ")"+"L"+retType+";"; } - desc = desc + ")"+"L"+resultSet.resolveType(samMethod.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+";"; return desc; } @@ -147,7 +172,7 @@ public class DescriptorToString implements DescriptorVisitor{ for(Expression e : methodFromMethodCall.getArgList().getArguments()) { String d = resultSet.resolveType(e.getType()).resolvedType.acceptTV(new TypeToDescriptor()); - if(d.substring(0, 4).equals("TPH ") ||d.contains("<")) { + if(d.substring(0, 4).equals("TPH ") ||d.contains("<") || methodFromMethodCall.getReceiverName().contains("$$")) { desc += "L"+Type.getInternalName(Object.class)+ ";"; }else { if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(d)) { @@ -164,7 +189,7 @@ public class DescriptorToString implements DescriptorVisitor{ System.out.println("DescriptorToString retType = " + retType); if(retType.equals("void")) { desc += ")V"; - }else if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<")){ + }else if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<") || methodFromMethodCall.getReceiverName().contains("$$")){ desc += ")L"+Type.getInternalName(Object.class)+ ";"; }else { if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(retType)) { diff --git a/src/de/dhbwstuttgart/bytecode/signature/Signature.java b/src/de/dhbwstuttgart/bytecode/signature/Signature.java index 7b222770c..11f3ca208 100644 --- a/src/de/dhbwstuttgart/bytecode/signature/Signature.java +++ b/src/de/dhbwstuttgart/bytecode/signature/Signature.java @@ -9,6 +9,7 @@ import org.objectweb.asm.signature.SignatureVisitor; import org.objectweb.asm.signature.SignatureWriter; import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor; +import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH; import de.dhbwstuttgart.syntaxtree.AbstractASTWalker; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.Constructor; @@ -16,9 +17,11 @@ import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; import de.dhbwstuttgart.syntaxtree.type.GenericRefType; +import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.result.GenericInsertPair; +import de.dhbwstuttgart.typeinference.result.ResolvedType; import de.dhbwstuttgart.typeinference.result.ResultSet; public class Signature { @@ -106,7 +109,7 @@ public class Signature { // z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()); if(ret.substring(0,4).equals("TPH ")) { - String g = ret.substring(4)+"$"; + String g = ret.substring(4,ret.length())+"$"; if(genericsAndBounds.containsKey(g)) { genericsAndBoundsMethod.put(g, genericsAndBounds.get(g)); }else { @@ -117,13 +120,21 @@ public class Signature { } } + if(ret.contains("<")) { + RefType ref = (RefType) resultSet.resolveType(method.getReturnType()).resolvedType; + if(hasTPHs(ref)) { + createSignatureForParameterizedType(ref); + } + + } + // Parameters for(String paramName : methodParamsAndTypes.keySet()) { RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName); String pT = t.acceptTV(new TypeToSignature()); // S.o if(pT.substring(0,4).equals("TPH ")) { - String gP = pT.substring(4)+"$"; + String gP = pT.substring(4,pT.length())+"$"; if(!genericsAndBounds.containsKey(gP) && !genericsAndBoundsMethod.containsKey(gP)) { sw.visitFormalTypeParameter(gP); String bound = Type.getInternalName(Object.class); @@ -147,6 +158,12 @@ public class Signature { } } + if(pT.contains("<")) { + RefType ref = (RefType) methodParamsAndTypes.get(paramName); + if(hasTPHs(ref)) + createSignatureForParameterizedType(ref); + } + for(GenericInsertPair p:methodPairs) { String name = p.TA1.getName()+"$"; if(!genericsAndBoundsMethod.containsKey(name)) { @@ -191,6 +208,142 @@ public class Signature { } // sw.visitEnd(); } + + private void createSignatureForParameterizedType(RefType ref) { + ArrayList allPairs = getAllPairs(ref); + allPairs.addAll(methodPairs); + ArrayList simplifiedPairs = simplifyPairs(allPairs); + + HashMap names = new HashMap<>(); + + for(GenericInsertPair pair : simplifiedPairs) { + if(ref.getParaList().contains(pair.TA1)) { + String sub = pair.TA1.getName()+"$"; + String superT = pair.TA2.getName()+"$"; + names.put(sub, superT); + } + } + + for(String sub : names.keySet()) { + if(!genericsAndBoundsMethod.containsKey(sub) && !genericsAndBounds.containsKey(sub)) { + sw.visitFormalTypeParameter(sub); + String bound = names.get(sub); + sw.visitClassBound().visitTypeVariable(bound); + genericsAndBoundsMethod.put(sub, bound); + } + } + + for(String superT : names.values()) { + if(!names.containsKey(superT)) { + if(!genericsAndBoundsMethod.containsKey(superT) && !genericsAndBounds.containsKey(superT)) { + sw.visitFormalTypeParameter(superT); + sw.visitClassBound().visitClassType(Type.getInternalName(Object.class)); + sw.visitClassBound().visitEnd(); + genericsAndBoundsMethod.put(superT, Type.getInternalName(Object.class)); + } + } + } + + for(RefTypeOrTPHOrWildcardOrGeneric p: ref.getParaList()) { + if(p instanceof TypePlaceholder) { + String name = ((TypePlaceholder) p).getName() + "$"; + if(!genericsAndBoundsMethod.containsKey(name) && !genericsAndBounds.containsKey(name)) { + sw.visitFormalTypeParameter(name); + sw.visitClassBound().visitClassType(Type.getInternalName(Object.class)); + sw.visitClassBound().visitEnd(); + genericsAndBoundsMethod.put(name, Type.getInternalName(Object.class)); + } + } + } + } + + private ArrayList getAllPairs(RefType ref) { + final ArrayList res = new ArrayList<>(); + for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) { + RefTypeOrTPHOrWildcardOrGeneric resolved = resultSet.resolveType(p).resolvedType; + if(resolved instanceof TypePlaceholder) { + resultSet.resolveType(p).additionalGenerics.forEach(ag ->{ + if(!contains(res,ag)) { + res.add(ag); + } + }); + } + + } + return res; + } + + private boolean contains(ArrayList pairs, GenericInsertPair genPair) { + for(int i=0; i simplifyPairs(ArrayList allPairs) { + ArrayList simplifiedPairs = new ArrayList<>(); + + HashMap subAndSuperTph = new HashMap<>(); + for(GenericInsertPair p : allPairs) { + subAndSuperTph.put(p.TA1, p.TA2); + } + + subAndSuperTph.forEach((k,v)->System.out.println(k.getName() + " || " + v.getName())); + + int numOfVisitedPairs = 0; + for(TypePlaceholder subTph: subAndSuperTph.keySet()) { + + if(numOfVisitedPairs>=subAndSuperTph.size()) + break; + + HashMap tphsInRel= new HashMap<>(); + + tphsInRel.put(tphsInRel.size(), subTph); + TypePlaceholder superTph = subAndSuperTph.get(subTph); + tphsInRel.put(tphsInRel.size(), superTph); + + numOfVisitedPairs++; + + while(subAndSuperTph.containsKey(superTph)) { + superTph = subAndSuperTph.get(superTph); + tphsInRel.put(tphsInRel.size(), superTph); + numOfVisitedPairs++; + } + + // Subtype + TypePlaceholder subTphRes = tphsInRel.get(0); + // Die größte Supertype + TypePlaceholder superTphRes = tphsInRel.get(tphsInRel.size()-1); + + + while(subAndSuperTph.containsValue(subTphRes)) { + for(TypePlaceholder tph : subAndSuperTph.keySet()) { + if(subAndSuperTph.get(tph).equals(subTphRes)) { + subTphRes = tph; + break; + } + } + tphsInRel.put(0, subTphRes); + numOfVisitedPairs++; + } + + subTphRes = tphsInRel.get(0); + GenericInsertPair sPair = new GenericInsertPair(subTphRes, superTphRes); + simplifiedPairs.add(sPair); + } + return simplifiedPairs; + } + + private boolean hasTPHs(RefType ref) { + for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) { + if(resultSet.resolveType(p).resolvedType instanceof TypePlaceholder) + return true; + } + return false; + } + /** * Visits parameter type or return type with {@link SignatureVisitor} to create * the method signature diff --git a/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java b/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java index a1357d4cf..62227c8e7 100644 --- a/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java +++ b/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java @@ -22,7 +22,12 @@ public class TypeToSignature implements TypeVisitor { Iterator it = refType.getParaList().iterator(); while(it.hasNext()){ RefTypeOrTPHOrWildcardOrGeneric param = it.next(); - params += "L"+param.toString().replace(".", "/"); + if(param instanceof TypePlaceholder) { + params += "T" + ((TypePlaceholder) param).getName() + "$"; + } else { + params += "L"+param.toString().replace(".", "/"); + } + if(it.hasNext())params += ";"; } params += ";>"; diff --git a/src/de/dhbwstuttgart/bytecode/utilities/MethodFromMethodCall.java b/src/de/dhbwstuttgart/bytecode/utilities/MethodFromMethodCall.java index cd8f53724..2028c7723 100644 --- a/src/de/dhbwstuttgart/bytecode/utilities/MethodFromMethodCall.java +++ b/src/de/dhbwstuttgart/bytecode/utilities/MethodFromMethodCall.java @@ -9,13 +9,16 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; public class MethodFromMethodCall { private ArgumentList argList; private RefTypeOrTPHOrWildcardOrGeneric returnType; + private String receiverName; private HashMap genericsAndBoundsMethod; private HashMap genericsAndBounds; - public MethodFromMethodCall(ArgumentList argList,RefTypeOrTPHOrWildcardOrGeneric returnType, - HashMap genericsAndBoundsMethod,HashMap genericsAndBounds) { + public MethodFromMethodCall(ArgumentList argList,RefTypeOrTPHOrWildcardOrGeneric returnType, + String receiverName, HashMap genericsAndBoundsMethod, + HashMap genericsAndBounds) { this.argList = argList; this.returnType = returnType; + this.receiverName = receiverName; this.genericsAndBoundsMethod = genericsAndBoundsMethod; this.genericsAndBounds = genericsAndBounds; } @@ -28,6 +31,10 @@ public class MethodFromMethodCall { return returnType; } + public String getReceiverName() { + return receiverName; + } + public HashMap getGenericsAndBoundsMethod(){ return genericsAndBoundsMethod; } diff --git a/src/de/dhbwstuttgart/syntaxtree/type/FunN.java b/src/de/dhbwstuttgart/syntaxtree/type/FunN.java index 84fe1ace1..46de6566d 100644 --- a/src/de/dhbwstuttgart/syntaxtree/type/FunN.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/FunN.java @@ -24,7 +24,7 @@ public class FunN extends RefType { * @return */ public FunN(List params) { - super(new JavaClassName("Fun"+params.size()), params, new NullToken()); + super(new JavaClassName("Fun"+(params.size())), params, new NullToken()); } /** diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java b/src/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java index 3518c16a3..0c8220f16 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java @@ -8,32 +8,36 @@ import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.NameGenerator; +import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; + import org.antlr.v4.runtime.Token; import java.util.ArrayList; import java.util.List; public class FunNClass extends ClassOrInterface { - public FunNClass(List funNParams) { - super(0, new JavaClassName("Fun"+(funNParams.size()-1)), new ArrayList<>(), + public FunNClass(List funNParams) { + super(0, new JavaClassName("Fun"+(funNParams.size())), new ArrayList<>(), createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams), ASTFactory.createObjectType(), true, new ArrayList<>(), new NullToken()); } - private static GenericDeclarationList createGenerics(List funNParams) { + private static GenericDeclarationList createGenerics(List funNParams) { + //PL 2018-06-22: so geaendert, dass generierte Generics den Namen der funParams entsprechen. List generics = new ArrayList<>(); - for(RefTypeOrTPHOrWildcardOrGeneric param : funNParams){ - generics.add(new GenericTypeVar(NameGenerator.makeNewName(), + for(GenericRefType param : funNParams){ + generics.add(new GenericTypeVar(param.getParsedName(),//NameGenerator.makeNewName(), new ArrayList<>(), new NullToken(), new NullToken())); } return new GenericDeclarationList(generics, new NullToken()); } - private static List createMethods(List funNParams) { + private static List createMethods(List funNParams) { return null; } } diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java index e17281e5f..294c85079 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java @@ -16,10 +16,10 @@ import java.util.List; public class MethodAssumption extends Assumption{ private ClassOrInterface receiver; private RefTypeOrTPHOrWildcardOrGeneric retType; - List params; + List params; public MethodAssumption(ClassOrInterface receiver, RefTypeOrTPHOrWildcardOrGeneric retType, - List params, TypeScope scope){ + List params, TypeScope scope){ super(scope); this.receiver = receiver; this.retType = retType; @@ -38,7 +38,9 @@ public class MethodAssumption extends Assumption{ } public RefTypeOrTPHOrWildcardOrGeneric getReturnType(GenericsResolver resolver) { - if(retType instanceof GenericRefType)return resolver.resolve(retType); + if(retType instanceof GenericRefType) { + return resolver.resolve(retType); + } return retType; } diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index 6b9f49190..83c37de31 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -6,6 +6,7 @@ import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; +import de.dhbwstuttgart.syntaxtree.factory.NameGenerator; import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption; @@ -327,7 +328,16 @@ public class TYPEStmt implements StatementVisitor{ @Override public void visit(Literal literal) { - //Nothing to do here. Literale erzeugen keine Constraints + //Nothing to do here. Literale erzeugen keine Constraints + //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 Double) { + // constraintsSet.addUndConstraint(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT)); + //} + //else { + // throw new NotImplementedException(); + //} } @Override @@ -451,11 +461,14 @@ public class TYPEStmt implements StatementVisitor{ List ret = new ArrayList<>(); //TODO: apply Methoden wieder anfügen. Diese könnten möglicherweise auch in den Assumptions auftauchen (überdenken) if(name.equals("apply")){ - List funNParams = new ArrayList<>(); + List funNParams = new ArrayList<>(); for(int i = 0; i< numArgs + 1 ; i++){ - funNParams.add(TypePlaceholder.fresh(new NullToken())); + //funNParams.add(TypePlaceholder.fresh(new NullToken())); + funNParams.add(new GenericRefType(NameGenerator.makeNewName(), + new NullToken())); } - ret.add(new MethodAssumption(new FunNClass(funNParams), funNParams.get(0), funNParams.subList(1, funNParams.size()), + funNParams.get(funNParams.size()-1); + ret.add(new MethodAssumption(new FunNClass(funNParams), funNParams.get(funNParams.size()-1), funNParams.subList(0, funNParams.size()-1), new TypeScope() { @Override public Iterable getGenerics() { @@ -498,7 +511,7 @@ public class TYPEStmt implements StatementVisitor{ */ List params = new ArrayList<>(); for(FormalParameter fp : parameterList.getFormalparalist()){ - params.add(info.checkGTV(fp.getType())); + params.add(fp.getType()); //info.checkGTV(fp.getType())); //PL 2018-06-22 GTV sollen in Argumenten erhalten bleiben } return params; } diff --git a/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java index 69e58bcce..f54b1eb11 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java @@ -933,7 +933,9 @@ public class RuleSet implements IRuleSet{ else { UnifyType freshTph = PlaceholderType.freshPlaceholder(); result.add(new UnifyPair(rhsType, new SuperType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair())); - result.add(new UnifyPair(freshTph, superedType, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair())); + Set fBounded = pair.getfBounded(); + fBounded.add(lhsType); + result.add(new UnifyPair(freshTph, superedType, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair(), fBounded)); } return Optional.of(result); diff --git a/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java b/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java index 47f0816f2..3ee49cdbd 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java +++ b/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java @@ -13,6 +13,7 @@ import java.util.Map.Entry; import java.util.Optional; import java.util.Set; import java.util.concurrent.RecursiveTask; +import java.util.function.BiFunction; import java.util.function.BinaryOperator; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -141,11 +142,12 @@ public class TypeUnifyTask extends RecursiveTask>> { * @return The set of all principal type unifiers */ protected Set> unify(Set eq, IFiniteClosure fc, boolean parallel) { - Set aas = eq.stream().filter(x -> x.getLhsType().getName().equals("AA") //&& x.getPairOp().equals(PairOperator.SMALLERDOT) - ).collect(Collectors.toCollection(HashSet::new)); - if (aas.isEmpty()) { - System.out.println(""); - } + //Set aas = eq.stream().filter(x -> x.getLhsType().getName().equals("AA") //&& x.getPairOp().equals(PairOperator.SMALLERDOT) + // ).collect(Collectors.toCollection(HashSet::new)); + //writeLog(nOfUnify.toString() + " AA: " + aas.toString()); + //if (aas.isEmpty()) { + // System.out.println(""); + //} /* * Step 1: Repeated application of reduce, adapt, erase, swap */ @@ -470,6 +472,7 @@ public class TypeUnifyTask extends RecursiveTask>> { Set> elems = new HashSet>(fstElems); elems.add(a); //if (remainingSets.isEmpty()) {//muss immer gegeben sein, weil nur 1 Element der topLevelSets mehr als ein Elemet enthaelt + //writeLog("Vor unify2 Aufruf: " + eq.toString()); Set> res = unify2(elems, eq, fc, parallel); if (!isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result)) { //wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen @@ -494,7 +497,8 @@ public class TypeUnifyTask extends RecursiveTask>> { //else {//duerfte gar nicht mehr vorkommen PL 2018-04-03 //result.addAll(computeCartesianRecursive(elems, remainingSets, eq, fc, parallel)); //} - + + /* auskommentiert um alle Max und min Betrachtung auszuschalten ANFANG */ if (!result.isEmpty() && !isUndefinedPairSetSet(res)) { if (nextSetasList.iterator().hasNext() && nextSetasList.iterator().next().stream().filter(x -> x.getLhsType().getName().equals("D")).findFirst().isPresent() && nextSetasList.size()>1) System.out.print(""); @@ -524,6 +528,8 @@ public class TypeUnifyTask extends RecursiveTask>> { } } } + /* auskommentiert um alle Max und min Betrachtung auszuschalten ENDE */ + if (isUndefinedPairSetSet(res)) { Set abhSubst = res.stream() .map(b -> @@ -1068,7 +1074,7 @@ public class TypeUnifyTask extends RecursiveTask>> { UnifyType supAPrime = new SuperType(aPrime); UnifyType thetaPrime = subThetaPrime.getSuperedType(); Set resultPrime = new HashSet<>(); - resultPrime.add(new UnifyPair(thetaPrime, a, PairOperator.SMALLERDOT, pair.getSubstitution(), pair)); + resultPrime.add(new UnifyPair(thetaPrime, a, PairOperator.SMALLERDOT, pair.getSubstitution(), pair, pair.getfBounded())); result.add(resultPrime); //writeLog(resultPrime.toString()); @@ -1098,14 +1104,34 @@ public class TypeUnifyTask extends RecursiveTask>> { break; } - for(UnifyType thetaS : fc.greater(theta, new HashSet<>())) { + for(UnifyType thetaS : fc.greater(theta, pair.getfBounded())) { Set resultPrime = new HashSet<>(); + Match match = new Match(); UnifyType[] freshTphs = new UnifyType[thetaS.getTypeParams().size()]; for(int i = 0; !allGen && i < freshTphs.length; i++) { freshTphs[i] = PlaceholderType.freshPlaceholder(); ((PlaceholderType)freshTphs[i]).setVariance(((PlaceholderType)a).getVariance()); - resultPrime.add(new UnifyPair(thetaS.getTypeParams().get(i), freshTphs[i], PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair)); + Set fBounded = pair.getfBounded(); + + int i_ef = i; + BiFunction f = (x,y) -> + { + ArrayList termList = new ArrayList(); + termList.add(new UnifyPair(y,thetaS.getTypeParams().get(i_ef), PairOperator.EQUALSDOT)); + return ((match.match(termList).isPresent()) || x); + }; + //if (parai.getName().equals("java.lang.Integer")) { + // System.out.println(""); + //} + BinaryOperator bo = (x,y) -> (x || y); + if (fBounded.stream().reduce(false,f,bo)) { + resultPrime.add(new UnifyPair(thetaS.getTypeParams().get(i), freshTphs[i], PairOperator.EQUALSDOT, pair.getSubstitution(), pair)); + } + else { + fBounded.add(thetaS.getTypeParams().get(i)); + resultPrime.add(new UnifyPair(thetaS.getTypeParams().get(i), freshTphs[i], PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair, fBounded)); + } } if(allGen) @@ -1139,9 +1165,9 @@ public class TypeUnifyTask extends RecursiveTask>> { ((PlaceholderType)freshTph).setVariance(a.getVariance()); resultPrime = new HashSet<>(); resultPrime.add(new UnifyPair(a, new ExtendsType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair)); - resultPrime.add(new UnifyPair(theta, freshTph, PairOperator.SMALLERDOT, pair.getSubstitution(), pair)); + resultPrime.add(new UnifyPair(theta, freshTph, PairOperator.SMALLERDOT, pair.getSubstitution(), pair, pair.getfBounded())); result.add(resultPrime); - //writeLog(resultPrime.toString()); + //writeLog("resultPrime: " + resultPrime.toString()); resultPrime = new HashSet<>(); resultPrime.add(new UnifyPair(a, new SuperType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair)); diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java b/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java index 8f5948444..f2bc52774 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java @@ -102,7 +102,7 @@ public class Unifier implements Function, Iterable fBounded = new HashSet<>(); private final int hashCode; @@ -82,6 +89,12 @@ public class UnifyPair { hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode(); } + public UnifyPair(UnifyType lhs, UnifyType rhs, PairOperator op, Set uni, UnifyPair base, Set fBounded) { + this(lhs, rhs, op, uni, base); + + this.fBounded = fBounded; + } + /** * Returns the type on the left hand side of the pair. */ @@ -138,6 +151,10 @@ public class UnifyPair { return lhs.wrongWildcard() || rhs.wrongWildcard(); } + public Set getfBounded() { + return this.fBounded; + } + @Override public boolean equals(Object obj) { if(!(obj instanceof UnifyPair)) @@ -177,7 +194,7 @@ public class UnifyPair { if (rhs instanceof PlaceholderType) { ret = ret + ", " + new Integer(((PlaceholderType)rhs).getVariance()).toString(); } - return "(" + lhs + " " + pairOp + " " + rhs + ", " + ret + ")"; + return "(" + lhs + " " + pairOp + " " + rhs + ", " + ret + ", [" + getfBounded().toString()+ "])"; } /* diff --git a/target/JavaTXcompiler-0.1-jar-with-dependencies.jar b/target/JavaTXcompiler-0.1-jar-with-dependencies.jar index 7b9d301bd..24018501c 100644 Binary files a/target/JavaTXcompiler-0.1-jar-with-dependencies.jar and b/target/JavaTXcompiler-0.1-jar-with-dependencies.jar differ diff --git a/test/bytecode/javFiles/Lambda.jav b/test/bytecode/javFiles/Lambda.jav index 3aeded259..af368a487 100644 --- a/test/bytecode/javFiles/Lambda.jav +++ b/test/bytecode/javFiles/Lambda.jav @@ -1,11 +1,16 @@ -import java.lang.Integer; +import java.util.Vector; +class Apply { } public class Lambda { m () { - var lam1 = (Integer x) -> { + var lam1 = (x) -> { return x; }; - return lam1; + + return lam1.apply(new Apply()); + //return lam1; + //return new Vector(); } } + diff --git a/test/bytecode/javFiles/Matrix.jav b/test/bytecode/javFiles/Matrix.jav index f0ea03563..eff095c76 100644 --- a/test/bytecode/javFiles/Matrix.jav +++ b/test/bytecode/javFiles/Matrix.jav @@ -8,9 +8,9 @@ public class Matrix extends Vector> { var i = 0; while(i < size()) { var v1 = this.elementAt(i); - var v2 = new Vector(); - var j = 0; - while(j < v1.size()) { +// var v2 = new Vector(); +// var j = 0; +// while(j < v1.size()) { // var erg = 0; // var k = 0; // while(k < v1.size()) { @@ -18,9 +18,9 @@ public class Matrix extends Vector> { // * m.elementAt(k).elementAt(j); // k++; } // v2.addElement(new Integer(erg)); - j++; } - ret.addElement(v2); - i++; +// j++; } +// ret.addElement(v2); +// i++; } return ret; } diff --git a/test/javFiles/Lambda.jav b/test/javFiles/Lambda.jav index a2feb8ee1..48359fc81 100644 --- a/test/javFiles/Lambda.jav +++ b/test/javFiles/Lambda.jav @@ -1,5 +1,4 @@ -import java.lang.Integer; -import java.lang.Number; +class Apply { } public class Lambda { @@ -7,7 +6,7 @@ public class Lambda { var lam1 = (Integer x) -> { return x; }; - return lam1.apply(1); + return lam1.apply(new Apply()); } } diff --git a/test/javFiles/Matrix.jav b/test/javFiles/Matrix.jav index 4c55c4103..5e1eac086 100644 --- a/test/javFiles/Matrix.jav +++ b/test/javFiles/Matrix.jav @@ -16,7 +16,7 @@ class Matrix extends Vector> { var k = 0; while(k < v1.size()) { erg = erg + v1.elementAt(k) * m.elementAt(k).elementAt(j); - // erg = add1(erg, mul1(v1.elementAt(k), + //erg = add1(erg, mul1(v1.elementAt(k), // m.elementAt(k).elementAt(j))); k++; } v2.addElement(new Integer(erg)); diff --git a/test/javFiles/Vector.jav b/test/javFiles/Vector.jav index 40072fe4f..5c21cfffa 100644 --- a/test/javFiles/Vector.jav +++ b/test/javFiles/Vector.jav @@ -1,8 +1,23 @@ +import java.util.ArrayList; import java.util.Vector; +import java.lang.Object; class MyVector{ id(x){ - return (x.elementAt(0)); + Object i; + x.add(i); + x.add(i); + x.add(i); + x.add(i); + x.add(i); + x.add(i); + x.add(i); + x.add(i); + x.add(i); + x.add(i); + x.add(i); + x.add(i); + return x; } } \ No newline at end of file diff --git a/test/typeinference/UnifyTest.java b/test/typeinference/UnifyTest.java index 6b2eeca29..f8b6ec2ef 100644 --- a/test/typeinference/UnifyTest.java +++ b/test/typeinference/UnifyTest.java @@ -28,13 +28,20 @@ public class UnifyTest { public void finiteClosure() throws IOException, ClassNotFoundException { execute(new File(rootDirectory+"fc.jav")); } - */ @Test public void lambda() throws IOException, ClassNotFoundException { execute(new File(rootDirectory+"Lambda.jav")); } + */ + /* + @Test + public void vector() throws IOException, ClassNotFoundException { + execute(new File(rootDirectory+"Vector.jav")); + } + */ + /* @Test public void lambda2() throws IOException, ClassNotFoundException { @@ -74,16 +81,14 @@ public class UnifyTest { } */ - -/* @Test public void matrix() throws IOException, ClassNotFoundException { execute(new File(rootDirectory+"Matrix.jav")); //JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"Matrix.jav")); //compiler.generateBytecode(); } -*/ + /* @Test public void vector() throws IOException, ClassNotFoundException {