diff --git a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java index ad07ca0f..d55e9349 100644 --- a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java +++ b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java @@ -3,31 +3,37 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.parser.antlr.Java8Parser; +import de.dhbwstuttgart.parser.antlr.Java8Parser.UnannClassType_lfno_unannClassOrInterfaceTypeContext; import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassRegistry; import de.dhbwstuttgart.syntaxtree.GenericDeclarationList; import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; +import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; - +import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import org.antlr.v4.runtime.Token; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class TypeGenerator { public static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.UnannClassOrInterfaceTypeContext unannClassOrInterfaceTypeContext, JavaClassRegistry reg, GenericsRegistry generics) { - Java8Parser.TypeArgumentsContext arguments; + Java8Parser.TypeArgumentsContext arguments=null; + /* PL 2019-03-19 auskommentiert ANFANG if(unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType() != null){ arguments = unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().typeArguments(); }else{// if(unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType() != null){ arguments = unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().unannClassType_lfno_unannClassOrInterfaceType().typeArguments(); } + PL 2019-03-19 auskommentiert ENDE */ /** * Problem sind hier die verschachtelten Typen mit verschachtelten Typargumenten * Beispiel: Typ.InnererTyp @@ -35,6 +41,28 @@ public class TypeGenerator { String name = unannClassOrInterfaceTypeContext.getText(); if(name.contains("<")){ name = name.split("<")[0]; //Der Typ ist alles vor den ersten Argumenten + /* Fuer Debug-Zwecke + unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType(); + unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().getText(); + //unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().unannClassType_lfno_unannClassOrInterfaceType().typeArguments(); + //UnannClassType_lfno_unannClassOrInterfaceTypeContext + unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType(0); + unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType(0).getText(); + unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType(1); + unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType(1).getText(); + unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().getText(); + //unannClassOrInterfaceTypeContext.unannInterfaceType_lf_unannClassOrInterfaceType(); + //unannClassOrInterfaceTypeContext.unannInterfaceType_lf_unannClassOrInterfaceType(0).getText(); + //unannClassOrInterfaceTypeContext.unannInterfaceType_lf_unannClassOrInterfaceType(1).getText(); + //unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().getText(); + */ + int lastElement = new ArrayList<>(unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType()).size()-1; + if (lastElement >=0) {//qualifizierter Name z.B.: java.util.Vector + arguments = unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType(lastElement).typeArguments(); + } + else { //unqualifizierter Name z.B.: Vector + arguments = unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().typeArguments(); + } } return convertTypeName(name, arguments, unannClassOrInterfaceTypeContext.getStart(), reg, generics); } @@ -132,6 +160,18 @@ public class TypeGenerator { throw new NotImplementedException(); } } + + public static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.WildcardContext wildcardContext, JavaClassRegistry reg, GenericsRegistry generics) { + if(wildcardContext.wildcardBounds() != null){ + if(wildcardContext.wildcardBounds().getText().substring(0, 7).equals("extends")){ + return new ExtendsWildcardType(convert(wildcardContext.wildcardBounds().referenceType(), reg, generics), wildcardContext.getStart()); + }else{ + return new SuperWildcardType(convert(wildcardContext.wildcardBounds().referenceType(), reg, generics), wildcardContext.getStart()); + } + }else{ + throw new NotImplementedException(); //Wildcard ohne Bound + } + } public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName(String name, Token offset, JavaClassRegistry reg, GenericsRegistry generics){ return convertTypeName(name, null, offset, reg, generics); @@ -139,12 +179,17 @@ public class TypeGenerator { public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName( String name, Java8Parser.TypeArgumentsContext typeArguments, Token offset, JavaClassRegistry reg, GenericsRegistry generics){ - if(!reg.contains(name)){ //Dann könnte es ein Generische Type sein + if(!reg.contains(name)){ //Dann könnte es ein generischer Type oder ein FunN$$-Type sein if(generics.contains(name)){ return new GenericRefType(name, offset); }else{ + Pattern p = Pattern.compile("Fun(\\d+)[$][$]"); + Matcher m = p.matcher(name); + if (m.matches()) {//es ist FunN$$-Type + return new RefType(new JavaClassName(name), convert(typeArguments, reg, generics), offset); + } else { throw new TypeinferenceException("Der Typ "+ name + " ist nicht vorhanden",offset); - } + }} } if(typeArguments == null){ List params = new ArrayList<>(); @@ -162,7 +207,7 @@ public class TypeGenerator { List ret = new ArrayList<>(); for(Java8Parser.TypeArgumentContext arg : typeArguments.typeArgumentList().typeArgument()){ if(arg.wildcard() != null){ - throw new NotImplementedException(); + ret.add(convert(arg.wildcard(), reg, generics)); }else{ ret.add(convert(arg.referenceType(), reg, generics)); } diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index a764db6e..7166d0c4 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -68,9 +68,6 @@ public class UnifyTypeFactory { public static UnifyType convert(RefTypeOrTPHOrWildcardOrGeneric t, Boolean innerType){ if(t instanceof GenericRefType){ return UnifyTypeFactory.convert((GenericRefType)t, innerType); - }else - if(t instanceof FunN){ - return UnifyTypeFactory.convert((FunN)t, innerType); }else if(t instanceof TypePlaceholder){ return UnifyTypeFactory.convert((TypePlaceholder)t, innerType); }else if(t instanceof ExtendsWildcardType){ @@ -86,13 +83,13 @@ public class UnifyTypeFactory { public static UnifyType convert(RefType t, Boolean innerType){ //Check if it is a FunN Type: - Pattern p = Pattern.compile("Fun(\\d+)"); + Pattern p = Pattern.compile("Fun(\\d+)[$][$]"); Matcher m = p.matcher(t.getName().toString()); boolean b = m.matches(); if(b){ Integer N = Integer.valueOf(m.group(1)); if((N + 1) == t.getParaList().size()){ - return convert(new FunN(t.getParaList()), false); + return convertFunN(t.getParaList(), false); } } UnifyType ret; @@ -108,11 +105,11 @@ public class UnifyTypeFactory { return ret; } - public static UnifyType convert(FunN t, Boolean innerType){ + public static UnifyType convertFunN(List paraList, Boolean innerType){ UnifyType ret; List params = new ArrayList<>(); - if(t.getParaList() != null && t.getParaList().size() > 0){ - for(RefTypeOrTPHOrWildcardOrGeneric pT : t.getParaList()){ + if(paraList != null && paraList.size() > 0){ + for(RefTypeOrTPHOrWildcardOrGeneric pT : paraList){ params.add(UnifyTypeFactory.convert(pT, false)); } } @@ -236,7 +233,7 @@ public class UnifyTypeFactory { } public static RefTypeOrTPHOrWildcardOrGeneric convert(FunNType t, Map tphs) { - RefType ret = new RefType(new JavaClassName(t.getName()+"$$"), convert(t.getTypeParams(), tphs), new NullToken()); + RefType ret = new RefType(new JavaClassName(t.getName()), convert(t.getTypeParams(), tphs), new NullToken()); return ret; } diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/type/FunN.java b/src/main/java/de/dhbwstuttgart/syntaxtree/type/FunN.java deleted file mode 100644 index dc521b87..00000000 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/type/FunN.java +++ /dev/null @@ -1,41 +0,0 @@ -package de.dhbwstuttgart.syntaxtree.type; - - -import de.dhbwstuttgart.parser.NullToken; -import de.dhbwstuttgart.parser.scope.JavaClassName; - -import java.util.List; - -/** - * @see Spezifikation "Complete Typeinference in Java 8" von Martin Plümicke - * "interface FunN { R apply(T1 arg1, T2 arg2, ... , TN argN); }" - * @author A10023 - Andreas Stadelmeier - * - * Bemerkung: - * FunN ist ein RefType. Der RefType ist nicht mit einem FunNInterface verbunden. - * - */ -public class FunN extends RefType { - /** - * @author Andreas Stadelmeier, a10023 - * Benötigt für den Typinferenzalgorithmus für Java 8 - * Generiert einen RefType auf eine FunN - Klasse. - * @param params - * @return - */ - public FunN(List params) { - super(new JavaClassName("Fun"+(params.size()-1)), params, new NullToken()); - } - - /** - * Spezieller Konstruktor um eine FunN ohne Returntype zu generieren - - protected FunN(List list){ - super("",0); - if(list==null)throw new NullPointerException(); - setT(list); - this.name = new JavaClassName("Fun"+list.size());//getName(); - } - */ - -} diff --git a/src/main/java/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java b/src/main/java/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java index 6067851e..d41baa06 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java @@ -21,7 +21,7 @@ import java.util.Optional; public class FunNClass extends ClassOrInterface { public FunNClass(List funNParams) { - super(0, new JavaClassName("Fun"+(funNParams.size())), new ArrayList<>(), Optional.empty() /* eingefuegt PL 2018-11-24 */, + super(0, new JavaClassName("Fun"+(funNParams.size()-1)), 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/main/java/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java b/src/main/java/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java index 3862d0eb..c1a6d449 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java @@ -1,10 +1,10 @@ package de.dhbwstuttgart.typeinference.assumptions; import de.dhbwstuttgart.parser.NullToken; +import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.TypeScope; -import de.dhbwstuttgart.syntaxtree.type.FunN; import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; @@ -63,7 +63,7 @@ public class MethodAssumption extends Assumption{ } RefTypeOrTPHOrWildcardOrGeneric receiverType; if(receiver instanceof FunNClass){ - receiverType = new FunN(params); + receiverType = new RefType(new JavaClassName(receiver.getClassName().toString()+"$$"), params, new NullToken()); // new FunN(params); }else{ receiverType = new RefType(receiver.getClassName(), params, new NullToken()); } diff --git a/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index 4fd14fbc..f1332cd4 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -65,7 +65,9 @@ public class TYPEStmt implements StatementVisitor{ //lambdaParams.add(0,tphRetType); constraintsSet.addUndConstraint( new Pair(lambdaExpression.getType(), - new FunN(lambdaParams),PairOperator.EQUALSDOT)); + new RefType(new JavaClassName("Fun"+(lambdaParams.size()-1)+"$$"), lambdaParams, new NullToken()), + //new FunN(lambdaParams), + PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint( new Pair(lambdaExpression.getReturnType(), tphRetType,PairOperator.EQUALSDOT)); diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java index f55c742a..c8311bf1 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java @@ -535,6 +535,7 @@ public class TypeUnifyTask extends RecursiveTask>> { Set eq0 = applyTypeUnificationRules(eq, fc); + eq0.forEach(x -> x.disableCondWildcards()); /* * Step 2 and 3: Create a subset eq1s of pairs where both sides are TPH and eq2s of the other pairs diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FunNType.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FunNType.java index 3e9f2ae6..37cf6a0a 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FunNType.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FunNType.java @@ -22,7 +22,7 @@ public class FunNType extends UnifyType { * Creates a FunN-Type with the specified TypeParameters. */ protected FunNType(TypeParams p) { - super("Fun"+(p.size()-1), p); + super("Fun"+(p.size()-1)+"$$", p); } /** diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java index 19f6010f..362b08ec 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java @@ -177,6 +177,20 @@ public class UnifyPair { } } + /** + * wenn in einem Paar bestehend aus 2 Typvariablen eine nicht wildcardtable ist, + * so beide auf nicht wildcardtable setzen + */ + public void disableCondWildcards() { + if (lhs instanceof PlaceholderType && rhs instanceof PlaceholderType + && (!((PlaceholderType)lhs).isWildcardable() || !((PlaceholderType)rhs).isWildcardable())) + { + ((PlaceholderType)lhs).disableWildcardtable(); + ((PlaceholderType)rhs).disableWildcardtable(); + } + + } + public Boolean wrongWildcard() { return lhs.wrongWildcard() || rhs.wrongWildcard(); } diff --git a/src/test/resources/bytecode/javFiles/Matrix.jav b/src/test/resources/bytecode/javFiles/Matrix.jav index 29505161..cfab616b 100644 --- a/src/test/resources/bytecode/javFiles/Matrix.jav +++ b/src/test/resources/bytecode/javFiles/Matrix.jav @@ -4,7 +4,7 @@ import java.lang.Float; //import java.lang.Byte; //import java.lang.Boolean; -public class Matrix extends Vector> { +public class Matrix extends Vector> { Matrix () { } @@ -19,7 +19,7 @@ public class Matrix extends Vector> { } } - mul(m) { + mul(java.util.Vector> m) { var ret = new Matrix(); var i = 0; while(i < size()) { diff --git a/src/test/resources/bytecode/javFiles/MatrixOP.jav b/src/test/resources/bytecode/javFiles/MatrixOP.jav index 0daef9bd..ce68f7cb 100644 --- a/src/test/resources/bytecode/javFiles/MatrixOP.jav +++ b/src/test/resources/bytecode/javFiles/MatrixOP.jav @@ -3,7 +3,7 @@ import java.lang.Integer; //import java.lang.Byte; import java.lang.Boolean; -public class MatrixOP extends Vector> { +public class MatrixOP extends Vector> { MatrixOP () { } @@ -18,10 +18,10 @@ public class MatrixOP extends Vector> { } } - public mul = (m1, m2) -> { +public mul = (m1, m2) -> { var ret = new MatrixOP(); var i = 0; - while(i < size()) { + while(i < m1.size()) { var v1 = m1.elementAt(i); var v2 = new Vector(); var j = 0; diff --git a/src/test/resources/bytecode/javFiles/Sorting.jav b/src/test/resources/bytecode/javFiles/Sorting.jav index 341a1a6b..486bfd71 100644 --- a/src/test/resources/bytecode/javFiles/Sorting.jav +++ b/src/test/resources/bytecode/javFiles/Sorting.jav @@ -14,10 +14,10 @@ sort(in){ return merge(sort(firstHalf), sort(secondHalf)); } */ -/* + - void sort(ArrayList a){ + void sort(a){ a = merge(a,a); } -*/ + } diff --git a/src/test/resources/javFiles/Faculty.jav b/src/test/resources/javFiles/Faculty.jav index 71f40515..ed201ff9 100644 --- a/src/test/resources/javFiles/Faculty.jav +++ b/src/test/resources/javFiles/Faculty.jav @@ -1,13 +1,14 @@ import java.lang.Integer; class Faculty { - - Integer mul(Integer x, Integer y) { + //fact; + + Integer mul(Integer x, Integer y) { return x; } - + m () { - var fact = (Integer x) -> { + var fact = (Integer x) -> { return mul(x, fact.apply(x)); }; return fact; diff --git a/src/test/resources/javFiles/mathStruc.jav b/src/test/resources/javFiles/mathStruc.jav index 93f901ce..c8518e5d 100644 --- a/src/test/resources/javFiles/mathStruc.jav +++ b/src/test/resources/javFiles/mathStruc.jav @@ -1,13 +1,8 @@ +class MathStruc { -class mathStruc { + A model; + + innerOp = o -> ms -> new MathStruc(o.apply(this.model, ms.model)); -mathStruc(A a) { } - -A model(){ A a; return a; } - -methode(){ -var innerOp = o -> ms -> - new mathStruc(o.apply(this.model(),ms.model())); - return innerOp; - } -} \ No newline at end of file + MathStruc(A m) { model=m; } + } \ No newline at end of file