From 6a1f5dc248e98dce61a42d5f0e43ff348f94a76f Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Fri, 22 Sep 2017 18:31:47 +0200 Subject: [PATCH] =?UTF-8?q?Unvollst=C3=A4ndiger=20Stand=20bei=20der=20Impl?= =?UTF-8?q?ementierung=20von=20Generics?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SyntaxTreeGenerator/SyntaxTreeGenerator.java | 11 ++++++----- .../parser/SyntaxTreeGenerator/TypeGenerator.java | 8 +++----- src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java | 9 ++++++++- .../dhbwstuttgart/syntaxtree/type/GenericRefType.java | 1 + src/de/dhbwstuttgart/syntaxtree/type/RefType.java | 2 +- .../typeinference/constraints/ConstraintsFactory.java | 3 ++- .../dhbwstuttgart/typeinference/result/ResultSet.java | 11 ++++++++--- .../typeinference/typeAlgo/TYPEStmt.java | 11 ++++++++++- test/javFiles/Generics.jav | 9 +++++++++ 9 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index f9df6fb3..a6feb543 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -137,7 +137,7 @@ public class SyntaxTreeGenerator{ Java8Parser.MethodHeaderContext header = methodDeclarationContext.methodHeader(); int modifiers = SyntaxTreeGenerator.convert(methodDeclarationContext.methodModifier()); GenericsRegistry localGenerics = createGenerics(methodDeclarationContext.methodHeader().typeParameters(), - parentClass, header.methodDeclarator().Identifier().getText()); + parentClass, header.methodDeclarator().Identifier().getText(), reg, generics); localGenerics.putAll(generics); return convert(modifiers, header, methodDeclarationContext.methodBody(),parentClass, superClass, localGenerics); } @@ -146,7 +146,7 @@ public class SyntaxTreeGenerator{ Java8Parser.MethodHeaderContext header = ctx.methodHeader(); int modifiers = SyntaxTreeGenerator.convertInterfaceModifier(ctx.interfaceMethodModifier()); - GenericsRegistry localGenerics = createGenerics(header.typeParameters(), parentClass, header.methodDeclarator().Identifier().getText()); + GenericsRegistry localGenerics = createGenerics(header.typeParameters(), parentClass, header.methodDeclarator().Identifier().getText(), reg, generics); localGenerics.putAll(generics); return convert(modifiers, header, ctx.methodBody(),parentClass, superClass, localGenerics); @@ -209,7 +209,7 @@ public class SyntaxTreeGenerator{ } } JavaClassName name = reg.getName(ctx.Identifier().getText()); - GenericsRegistry generics = createGenerics(ctx.typeParameters(), name, ""); + GenericsRegistry generics = createGenerics(ctx.typeParameters(), name, "", reg, new GenericsRegistry(globalGenerics)); Token offset = ctx.getStart(); GenericDeclarationList genericClassParameters; if(ctx.typeParameters() == null){ @@ -412,7 +412,7 @@ public class SyntaxTreeGenerator{ } JavaClassName name = reg.getName(ctx.Identifier().getText()); - GenericsRegistry generics = createGenerics(ctx.typeParameters(), name, ""); + GenericsRegistry generics = createGenerics(ctx.typeParameters(), name, "", reg, new GenericsRegistry(globalGenerics)); GenericDeclarationList genericParams; if(ctx.typeParameters() != null){ @@ -438,8 +438,9 @@ public class SyntaxTreeGenerator{ return new GenericDeclarationList(new ArrayList<>(), gtvOffset); } - private GenericsRegistry createGenerics(Java8Parser.TypeParametersContext ctx, JavaClassName parentClass, String parentMethod) { + private GenericsRegistry createGenerics(Java8Parser.TypeParametersContext ctx, JavaClassName parentClass, String parentMethod, JavaClassRegistry reg, GenericsRegistry generics) { GenericsRegistry ret = new GenericsRegistry(this.globalGenerics); + ret.putAll(generics); if(ctx == null || ctx.typeParameterList() == null)return ret; for(Java8Parser.TypeParameterContext tp : ctx.typeParameterList().typeParameter()){ TypeGenerator.convert(tp, parentClass, parentMethod, reg, ret); diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java index a348622f..55c14bc7 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java @@ -69,6 +69,8 @@ public class TypeGenerator { public static GenericTypeVar convert(Java8Parser.TypeParameterContext typeParameter, JavaClassName parentClass, String parentMethod, JavaClassRegistry reg, GenericsRegistry generics) { String name = typeParameter.Identifier().getText(); + //TODO: Es müssen erst alle GenericTypeVars generiert werden, dann können die bounds dieser Generics ermittelt werden + //Problem ist erlaubt, würde aber bei den Bounds von A den Generic B nicht als solchen erkennen List bounds = TypeGenerator.convert(typeParameter.typeBound(),reg, generics); GenericTypeVar ret = new GenericTypeVar(new GenericTypeName(new GenericContext(parentClass, parentMethod), name), bounds, typeParameter.getStart(), typeParameter.getStop()); @@ -83,7 +85,7 @@ public class TypeGenerator { return ret; } if(typeBoundContext.typeVariable() != null){ - ret.add(convert(typeBoundContext.typeVariable())); + ret.add(convertTypeName(typeBoundContext.typeVariable().Identifier().getText(), null, typeBoundContext.typeVariable().getStart(), reg, generics)); return ret; } if(typeBoundContext.classOrInterfaceType() != null){ @@ -106,10 +108,6 @@ public class TypeGenerator { throw new NotImplementedException(); } - private static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.TypeVariableContext typeVariableContext) { - throw new NotImplementedException(); - } - public static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.ReferenceTypeContext referenceTypeContext, JavaClassRegistry reg, GenericsRegistry generics) { return convertTypeName(referenceTypeContext.getText(), referenceTypeContext.getStart(), reg, generics); } diff --git a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java index 12d04da2..f377e820 100755 --- 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.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.type.RefType; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.typeinference.constraints.Constraint; @@ -63,7 +64,13 @@ public class ClassOrInterface extends SyntaxTreeNode { } public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass ,Token offset){ - return new RefType(name, offset); + //Hier wird immer ein generischer Typ generiert, also mit Type placeholdern + List params = new ArrayList<>(); + for(GenericTypeVar genericTypeVar : genericsOfClass){ + //params.add(genericTypeVar.getTypePlaceholder()); + params.add(TypePlaceholder.fresh(offset)); + } + return new RefType(name, params, offset); } public RefTypeOrTPHOrWildcardOrGeneric getSuperClass() { diff --git a/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java b/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java index 9bd41cf2..121a6c99 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java @@ -9,6 +9,7 @@ import org.antlr.v4.runtime.Token; public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric { private GenericTypeName name; + public GenericRefType(GenericTypeName name, Token offset) { super(offset); diff --git a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java index 3a2f26e9..2951062b 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java @@ -30,7 +30,7 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric public RefType(JavaClassName fullyQualifiedName, Token offset) { - this(fullyQualifiedName, null, offset); + this(fullyQualifiedName, new ArrayList<>(), offset); } @Override diff --git a/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java b/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java index 909f94d2..8ef71e7f 100644 --- a/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java +++ b/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java @@ -29,7 +29,8 @@ public class ConstraintsFactory { } } //Nicht in den Generics in diesem Kontext enthalten: - return TypePlaceholder.fresh(type.getOffset()); + TypePlaceholder ret = TypePlaceholder.fresh(type.getOffset()); + return ret; }else{ return type; } diff --git a/src/de/dhbwstuttgart/typeinference/result/ResultSet.java b/src/de/dhbwstuttgart/typeinference/result/ResultSet.java index fef925ea..6a1d67f9 100644 --- a/src/de/dhbwstuttgart/typeinference/result/ResultSet.java +++ b/src/de/dhbwstuttgart/typeinference/result/ResultSet.java @@ -167,27 +167,31 @@ class RelatedTypeWalker implements ResultSetVisitor { /** * Läuft über das resultSet und speichert alle TPHs, welche mit start in Verbindung stehen - * @param start + * @param start - kann null sein, wenn der Walker für einen RefType benutzt wird * @param resultSet */ RelatedTypeWalker(TypePlaceholder start, ResultSet resultSet){ this.toResolve = start; this.resultSet = resultSet; + int resolved = 0; + do{ + resolved = relatedTPHs.size(); for(ResultPair p : resultSet.results){ p.accept(this); p.accept(this); } + }while(resolved - relatedTPHs.size() > 0); } @Override public void visit(PairTPHsmallerTPH p) { if(p.getRight().equals(toResolve)){ relatedTPHs.addAll(new TPHResolver(p.right, resultSet).resolved); - relatedTPHs.addAll(new RelatedTypeWalker(p.right, resultSet).relatedTPHs); + //relatedTPHs.addAll(new RelatedTypeWalker(p.right, resultSet).relatedTPHs); } if(p.getLeft().equals(toResolve)){ relatedTPHs.addAll(new TPHResolver(p.left, resultSet).resolved); - relatedTPHs.addAll(new RelatedTypeWalker(p.left, resultSet).relatedTPHs); + //relatedTPHs.addAll(new RelatedTypeWalker(p.left, resultSet).relatedTPHs); } } @@ -200,6 +204,7 @@ class RelatedTypeWalker implements ResultSetVisitor { /* Die folgenden Funktionen fügen alle TPHs an die relatedTPHs an, denen sie begegnen: + Das wird verwendet, wenn alle relatedTPHs aus den Parametern eines RefTypes angefügt werden sollen */ @Override diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index 3d6fdf5d..73842ac9 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -295,6 +295,15 @@ public class TYPEStmt implements StatementVisitor{ } protected static List convertParams(ParameterList parameterList, TypeInferenceBlockInformation info){ + //TODO: Hier müssen die Parameter mit den TPHs in den GEnerics des Receivers verknüpft werden + /* + BEispiel: + auto test = new List(); + test.add("hallo"); + + Hier kriegt der Receiver ja den COnstraint TPH REceiver <. List + Dann mus bei dem Parameter der COnstraint entstehen: TPH A <. String + */ List params = new ArrayList<>(); for(FormalParameter fp : parameterList.getFormalparalist()){ params.add(info.checkGTV(fp.getType())); @@ -308,7 +317,7 @@ public class TYPEStmt implements StatementVisitor{ if(cl.getClassName().equals(ofType.getName())){ for(Method m : cl.getConstructors()){ if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){ - ret.add(new MethodAssumption(ofType, ofType, convertParams(m.getParameterList(), info))); + ret.add(new MethodAssumption(cl.getType(), ofType, convertParams(m.getParameterList(), info))); } } } diff --git a/test/javFiles/Generics.jav b/test/javFiles/Generics.jav index 477d2296..c49f5dfb 100644 --- a/test/javFiles/Generics.jav +++ b/test/javFiles/Generics.jav @@ -10,3 +10,12 @@ class Test { return new Generics().mt1(s,s); } } + +/* +Problem: +auto test = new List(); +auto test2 = new List(); +... //code, welcher möglicherweise test und test2 vertauscht +test.add("hallo"); + +*/ \ No newline at end of file