diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index 39213e7b..b965d5c6 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -2,6 +2,7 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.ClassNotFoundException; +import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.PackageCrawler; import de.dhbwstuttgart.parser.antlr.Java8Parser; import de.dhbwstuttgart.syntaxtree.*; @@ -19,6 +20,7 @@ import java.util.HashMap; import java.util.List; //import jdk.internal.dynalink.support.TypeConverterFactory; +import org.antlr.v4.runtime.CommonToken; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.TerminalNode; @@ -213,6 +215,8 @@ public class SyntaxTreeGenerator{ GenericDeclarationList gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), header.getStart()); if(header.typeParameters() != null){ gtvDeclarations = TypeGenerator.convert(header.typeParameters(), parentClass, name,reg, localGenerics); + }else{ + gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), header.getStart()); } RefTypeOrTPHOrWildcardOrGeneric retType; if(header.result() != null){ @@ -263,7 +267,14 @@ public class SyntaxTreeGenerator{ JavaClassName name = reg.getName(ctx.Identifier().getText()); GenericsRegistry generics = createGenerics(ctx.typeParameters(), name, ""); Token offset = ctx.getStart(); - GenericDeclarationList genericClassParameters = TypeGenerator.convert(ctx.typeParameters(), name, "",reg, generics); + GenericDeclarationList genericClassParameters; + if(ctx.typeParameters() == null){ + CommonToken gtvOffset = new CommonToken(ctx.Identifier().getSymbol()); + gtvOffset.setCharPositionInLine(gtvOffset.getCharPositionInLine()+ctx.Identifier().getText().length()); + genericClassParameters = new GenericDeclarationList(new ArrayList<>(), gtvOffset); + }else{ + genericClassParameters = TypeGenerator.convert(ctx.typeParameters(), name, "",reg, generics); + } List fielddecl = convertFields(ctx.classBody(), generics); List methods = convertMethods(ctx.classBody(), name, generics); List konstruktoren = new ArrayList<>(); @@ -464,8 +475,14 @@ public class SyntaxTreeGenerator{ List fields = convertFields(ctx.interfaceBody()); List methods = convertMethods(ctx.interfaceBody(), name, generics); - - GenericDeclarationList genericParams = TypeGenerator.convert(ctx.typeParameters(), name, "",reg, generics); + GenericDeclarationList genericParams; + if(ctx.typeParameters() != null){ + genericParams = TypeGenerator.convert(ctx.typeParameters(), name, "",reg, generics); + }else{ + CommonToken gtvOffset = new CommonToken(ctx.Identifier().getSymbol()); + gtvOffset.setCharPositionInLine(gtvOffset.getCharPositionInLine()+ctx.Identifier().getText().length()); + genericParams = new GenericDeclarationList(new ArrayList<>(), gtvOffset); + } RefType superClass = new ASTFactory(reg).createObjectClass().getType(); List extendedInterfaces = convert(ctx.extendsInterfaces(), generics); diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java index 124f5eeb..605e76b5 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java @@ -4,7 +4,6 @@ import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.antlr.Java8Parser; -import de.dhbwstuttgart.syntaxtree.GTVDeclarationContext; import de.dhbwstuttgart.syntaxtree.GenericDeclarationList; import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; @@ -55,9 +54,6 @@ public class TypeGenerator { } public static GenericDeclarationList convert(Java8Parser.TypeParametersContext typeParametersContext, JavaClassName parentClass, String parentMethod, JavaClassRegistry reg, GenericsRegistry generics) { - if(typeParametersContext == null){ - return new GenericDeclarationList(new ArrayList<>(), new NullToken()); - } Token endOffset = typeParametersContext.getStop(); List typeVars = new ArrayList<>(); for(Java8Parser.TypeParameterContext typeParameter : typeParametersContext.typeParameterList().typeParameter()){ diff --git a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java index 38281048..79098e4d 100755 --- a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java +++ b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java @@ -15,7 +15,7 @@ import java.util.List; /** * Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces */ -public class ClassOrInterface extends GTVDeclarationContext implements IItemWithOffset, Generic{ +public class ClassOrInterface implements IItemWithOffset{ protected int modifiers; protected JavaClassName name; private List fields = new ArrayList<>(); @@ -29,25 +29,15 @@ public class ClassOrInterface extends GTVDeclarationContext implements IItemWith public ClassOrInterface(int modifiers, JavaClassName name, List fielddecl, List methods, List constructors, GenericDeclarationList genericClassParameters, RefTypeOrTPHOrWildcardOrGeneric superClass, Boolean isInterface, List implementedInterfaces, Token offset){ - super(offset); - this.modifiers = modifiers; - if(name != null){ - this.name = name; - } - if(fielddecl != null){ - this.fields = fielddecl; - } - if(genericClassParameters != null){ - this.genericClassParameters = genericClassParameters; - } this.offset = offset; - if(superClass != null){ + this.modifiers = modifiers; + this.name = name; + this.fields = fielddecl; + this.genericClassParameters = genericClassParameters; + this.offset = offset; this.superClass = superClass; - } this.isInterface = isInterface; - if(implementedInterfaces != null){ this.implementedInterfaces = implementedInterfaces; - } this.methods = methods; this.constructors = constructors; } @@ -96,4 +86,9 @@ public class ClassOrInterface extends GTVDeclarationContext implements IItemWith public List getConstructors() { return constructors; } + + @Override + public Token getOffset() { + return offset; + } } diff --git a/src/de/dhbwstuttgart/syntaxtree/Field.java b/src/de/dhbwstuttgart/syntaxtree/Field.java index 6c0fd84b..4961443c 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Field.java +++ b/src/de/dhbwstuttgart/syntaxtree/Field.java @@ -3,7 +3,7 @@ package de.dhbwstuttgart.syntaxtree; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import org.antlr.v4.runtime.Token; -public class Field extends GTVDeclarationContext implements Generic { +public class Field extends SyntaxTreeNode{ private String name; private RefTypeOrTPHOrWildcardOrGeneric type; diff --git a/src/de/dhbwstuttgart/syntaxtree/GTVDeclarationContext.java b/src/de/dhbwstuttgart/syntaxtree/GTVDeclarationContext.java deleted file mode 100644 index 34ff9542..00000000 --- a/src/de/dhbwstuttgart/syntaxtree/GTVDeclarationContext.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.dhbwstuttgart.syntaxtree; - -import org.antlr.v4.runtime.Token; - -/** - * Beischreibt eine SyntaxTreeNode, welcher die Eigenschaft besitzt, - * dass bei seiner Deklaration auch Generische Typvariablen deklariert wurden. - */ -public abstract class GTVDeclarationContext extends SyntaxTreeNode { - public GTVDeclarationContext(Token offset) { - super(offset); - } -} diff --git a/src/de/dhbwstuttgart/syntaxtree/Generic.java b/src/de/dhbwstuttgart/syntaxtree/Generic.java deleted file mode 100644 index 227ccc5b..00000000 --- a/src/de/dhbwstuttgart/syntaxtree/Generic.java +++ /dev/null @@ -1,9 +0,0 @@ -package de.dhbwstuttgart.syntaxtree; - -/** - * Wird von allen Klassen implementiert, welche generische Parameter halten können. (Class, Method und Field) - * @author janulrich - * - */ -public interface Generic { -} \ No newline at end of file diff --git a/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java b/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java index 8c2e1a82..0dbe8192 100644 --- a/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java +++ b/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java @@ -10,6 +10,7 @@ import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.constraints.Pair; import org.antlr.v4.runtime.Token; +import java.lang.reflect.Type; import java.util.*; /** @@ -47,65 +48,72 @@ public class TypeInsertFactory { return ret; } - private static Set createInsertPoints(RefTypeOrTPHOrWildcardOrGeneric type, Token offset, ClassOrInterface cl, Method m, Set pairs) { + private static Set createInsertPoints(RefTypeOrTPHOrWildcardOrGeneric type, Token offset, ClassOrInterface cl, Method m, + Set pairs) { Set ret = new HashSet<>(); - for(Pair pair : pairs){ + Set additionalInserts = new HashSet<>(); + for (Pair pair : pairs) { RefTypeOrTPHOrWildcardOrGeneric relatedType = null; - if(pair.TA1.equals(type) ){ + if (pair.TA1.equals(type)) { relatedType = pair.TA2; - } else if(pair.TA2.equals(type)){ + } else if (pair.TA2.equals(type)) { relatedType = pair.TA1; } - if(relatedType != null){ + if (relatedType != null) { //Es wurde ein direkter Treffer gefunden: - if(pair.OperatorEqual()){ //type ist vom Typ TypePlaceholder - type = relatedType; - }else{ - ret.addAll(createInsertPoints(relatedType, offset, cl, m, pairs)); + if (pair.OperatorEqual()) { //resolved ist vom Typ RefType + RefType resolved = ((RefType) relatedType); + String insert = createInsertString(resolved, additionalInserts); + ret.add(new TypeInsertPoint(offset, insert)); + } else { //Ansonsten ist es ein TPH + additionalInserts.add((TypePlaceholder) type); + //Dann wurde er nicht aufgelöst und es kann nur der TPH als Generic eingesetzt werden: + ret.add(new TypeInsertPoint(offset, ((TypePlaceholder) type).getName())); } } } - ret.addAll(new TypeInsertPointCreator(type, offset).createPoints()); + //Alle TPHs die man noch als Generics anfügen muss einsetzen: + //TODO + return ret; } -} - -class TypeInsertPointCreator{ - - private final RefTypeOrTPHOrWildcardOrGeneric type; - private final Token offset; - List ret = new ArrayList<>(); - - TypeInsertPointCreator(RefTypeOrTPHOrWildcardOrGeneric type, Token offset){ - this.type = type; - this.offset = offset; - } - - public List createPoints(){ - if(type instanceof RefType){ - RefType refType = ((RefType) type); - String insert = refType.getName().toString()+"<"; - for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){ + private static String createInsertString(RefType resolved, Set additionalInserts) { + String insert = resolved.getName().toString(); + if(resolved.getParaList().size() > 0){ + insert += "<"; + Iterator iterator = resolved.getParaList().iterator(); + while(iterator.hasNext()){ + RefTypeOrTPHOrWildcardOrGeneric typeParam = iterator.next(); + if(typeParam instanceof TypePlaceholder){ + insert += ((TypePlaceholder) typeParam).getName(); + additionalInserts.add((TypePlaceholder) typeParam); + }else if(typeParam instanceof RefType){ + insert += createInsertString((RefType) typeParam, additionalInserts); + }else throw new NotImplementedException(); + if(iterator.hasNext())insert += ", "; } insert += ">"; - ret.add(new TypeInsertPoint(offset, insert)); - }else { - ret.add(new TypeInsertPoint(offset, getInsertString(type))); } - return ret; + return insert; } - private String getInsertString(RefTypeOrTPHOrWildcardOrGeneric resolved) { - if(resolved instanceof RefType){ - //TODO: Kontrollieren, ob der Reftype und seine Parameter bekannt sind, ansonsten auch einsetzen - return ((RefType) resolved).getName().toString(); - }else if(resolved instanceof TypePlaceholder){ - return ((TypePlaceholder) resolved).getName(); - }else if(resolved instanceof GenericRefType){ - return ((GenericRefType)resolved).getName().getShortName().toString(); + private static TypeInsertPoint createGenericInsert(TypePlaceholder tph, TypePlaceholder bound, ClassOrInterface cl, Method m){ + //Momentan wird Methode ignoriert. Parameter werden immer als Klassenparameter angefügt: + Token offset; + String insert = ""; + String end =" "; + if(cl.getGenerics().iterator().hasNext()){ + offset = cl.getGenerics().iterator().next().getOffset(); }else{ - throw new NotImplementedException(); + offset = cl.getGenerics().getOffset(); + insert += "<"; + end = ">"; } + insert += tph.getName(); + if(bound != null){ + insert += " extends " + bound.getName(); + } + return new TypeInsertPoint(offset, insert + end); } } \ No newline at end of file diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java index abcee805..3fe36ecb 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java @@ -39,27 +39,10 @@ public class TYPE implements StatementVisitor{ @Override public void visit(LambdaExpression lambdaExpression) { - /* - List methodAssumptionss = getMethods("apply", lambdaExpression.params.getFormalparalist().size(), info); - //TODO: Nur FunN-Interface als mögliche Typen verwenden - //methodAssumptionss.stream().filter((methodAssumption -> methodAssumption.getReceiverType().getName().toString())) - Set possibleLambdaTypes = new HashSet<>(); - - for(MethodAssumption mAss : methodAssumptionss){ - Constraint cons = new Constraint(); - cons.add( - ConstraintsFactory.createPair(lambdaExpression.methodBody.getType(),mAss.getReturnType(),info)); - cons.add( - ConstraintsFactory.createPair(lambdaExpression.getType(),mAss.getReceiverType(),PairOperator.EQUALSDOT, info)); - possibleLambdaTypes.add(cons); - } - if(methodAssumptionss.size() == 0)throw new TypeinferenceException("Kein passendes Funktionales Interface für Lambda Ausdruck gefunden", lambdaExpression.getOffset()); - - constraintsSet.addOderConstraint(possibleLambdaTypes); - */ TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken()); List lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList()); - lambdaParams.add(tphRetType); + //lambdaParams.add(tphRetType); + lambdaParams.add(0,tphRetType); constraintsSet.addUndConstraint( ConstraintsFactory.createPair(lambdaExpression.getType(), new FunN(lambdaParams),PairOperator.EQUALSDOT,info)); diff --git a/test/javFiles/Lambda.jav b/test/javFiles/Lambda.jav index 6ec358b3..b0b98cbc 100644 --- a/test/javFiles/Lambda.jav +++ b/test/javFiles/Lambda.jav @@ -1,14 +1,14 @@ class Lambda{ -String var; methode(){ + String var; return () -> (f) -> { f.apply(this, var); return var; }; } } - +/* interface Fun0{ A apply(); } @@ -16,7 +16,7 @@ interface Fun0{ interface Fun1{ A apply(B b); } - +*/ interface Fun2{ A apply(B b, C c); } \ No newline at end of file