From 583dfb23e354dbd97a6fcece388ffe65880ad127 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Tue, 9 Sep 2014 11:15:10 +0200 Subject: [PATCH] Probleme mit GenericTypeVar behoben --- src/de/dhbwstuttgart/syntaxtree/Class.java | 12 +++++++++++- src/de/dhbwstuttgart/syntaxtree/Field.java | 12 +++++++++--- .../syntaxtree/FieldDeclaration.java | 2 +- src/de/dhbwstuttgart/syntaxtree/Method.java | 1 + .../syntaxtree/SyntaxTreeNode.java | 3 ++- .../syntaxtree/statement/LocalVarDecl.java | 1 + .../syntaxtree/statement/MethodCall.java | 2 +- .../syntaxtree/type/GenericTypeVar.java | 18 +++++++++++++++++- .../typeinference/Overloading.java | 18 ++++-------------- .../assumptions/TypeAssumptions.java | 3 --- .../TypeInsertTests/LambdaTest24.jav | 10 ++++++++++ .../TypeInsertTests/LambdaTest24.java | 16 ++++++++++++++++ 12 files changed, 73 insertions(+), 25 deletions(-) create mode 100644 test/plugindevelopment/TypeInsertTests/LambdaTest24.jav create mode 100644 test/plugindevelopment/TypeInsertTests/LambdaTest24.java diff --git a/src/de/dhbwstuttgart/syntaxtree/Class.java b/src/de/dhbwstuttgart/syntaxtree/Class.java index d8a66302c..275666ddd 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Class.java +++ b/src/de/dhbwstuttgart/syntaxtree/Class.java @@ -1129,6 +1129,15 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit this.addField(standardKonstruktor); } + if(this.genericClassParameters == null)this.setGenericParameter(new GenericDeclarationList(new Vector(), 0)); + for(Type t : this.get_ParaList()){ + if(t instanceof GenericTypeVar)this.genericClassParameters.add((GenericTypeVar)t); + else this.genericClassParameters.add(new GenericTypeVar(t.get_Name(),this,-1)); + } + for(GenericTypeVar gtv : this.getGenericParameter()){ + gtv.setParentClass(this);; + } + //TODO: Umwandlung zu RefTypes funktioniert noch nicht richtig. (siehe LambdaTest2) //Als RefType geparste Generische Variablen umwandeln: this.wandleRefTypeAttributes2GenericAttributes(); @@ -1144,6 +1153,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit Vector ret = new Vector(); for(Field f : this.getFields()){ ret.add(f); + ret.addAll(this.getGenericParameter()); } return ret; } @@ -1158,7 +1168,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit } @Override - public Iterable getGenericParameter() { + public Vector getGenericParameter() { if(this.genericClassParameters == null)return new Vector(); return this.genericClassParameters; } diff --git a/src/de/dhbwstuttgart/syntaxtree/Field.java b/src/de/dhbwstuttgart/syntaxtree/Field.java index 51930b346..baefadddb 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Field.java +++ b/src/de/dhbwstuttgart/syntaxtree/Field.java @@ -54,7 +54,7 @@ public abstract class Field extends SyntaxTreeNode implements TypeInsertable, Ty throws JVMCodeException; @Override - public Iterable getGenericParameter() { + public Vector getGenericParameter() { Vector ret = new Vector<>(); if(this.genericParameters == null)return ret; ret.addAll(this.genericParameters); @@ -153,10 +153,16 @@ public abstract class Field extends SyntaxTreeNode implements TypeInsertable, Ty return this.offset; } } - + + @Override + public Vector getChildren() { + Vector ret = new Vector<>(); + if(this.getType()!=null)ret.add(this.getType()); + return ret; + } + @Override public void setGenericParameter(GenericDeclarationList params) { this.genericParameters = params; } - } diff --git a/src/de/dhbwstuttgart/syntaxtree/FieldDeclaration.java b/src/de/dhbwstuttgart/syntaxtree/FieldDeclaration.java index 4f2e5a4d5..ebf61dd93 100644 --- a/src/de/dhbwstuttgart/syntaxtree/FieldDeclaration.java +++ b/src/de/dhbwstuttgart/syntaxtree/FieldDeclaration.java @@ -106,7 +106,7 @@ public class FieldDeclaration extends Field{ @Override public Vector getChildren() { - Vector ret = new Vector(); + Vector ret = super.getChildren(); if(this.wert!=null)ret.add(this.wert); return ret; } diff --git a/src/de/dhbwstuttgart/syntaxtree/Method.java b/src/de/dhbwstuttgart/syntaxtree/Method.java index 777b8be4b..db84fb99e 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Method.java +++ b/src/de/dhbwstuttgart/syntaxtree/Method.java @@ -683,6 +683,7 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable for(FormalParameter param : this.parameterlist){ ret.add(param); } + ret.addAll(this.getGenericParameter()); return ret; } diff --git a/src/de/dhbwstuttgart/syntaxtree/SyntaxTreeNode.java b/src/de/dhbwstuttgart/syntaxtree/SyntaxTreeNode.java index 7e621eebe..addee2d73 100644 --- a/src/de/dhbwstuttgart/syntaxtree/SyntaxTreeNode.java +++ b/src/de/dhbwstuttgart/syntaxtree/SyntaxTreeNode.java @@ -30,7 +30,8 @@ public abstract class SyntaxTreeNode implements IItemWithOffset{ */ public void parserPostProcessing(SyntaxTreeNode parent) { this.parent = parent; - for(SyntaxTreeNode node : this.getChildren())node.parserPostProcessing(this); + for(SyntaxTreeNode node : this.getChildren()) + if(node!=null)node.parserPostProcessing(this); } public SyntaxTreeNode getParent() { diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java b/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java index 048cab24a..fe5a0244e 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java @@ -423,6 +423,7 @@ public class LocalVarDecl extends Statement implements TypeInsertable @Override public Vector getChildren() { Vector ret = new Vector(); + if(this.getType()!=null)ret.add(this.getType()); return ret; } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java index e635fdf42..ff1f891e2 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java @@ -175,7 +175,7 @@ public class MethodCall extends Expr * Mögliche Probleme: * Wenn die Methode ohne Angabe eines Receivers im Quelltext steht: * methodCall(param); -> (bedeutet:) this.methodCall(param); - * Der Parser macht hier aber komische Faxen (siehe JavaParser.jay Zeile 1858 ff) + * Parser möglicherweise anpassen (siehe JavaParser.jay Zeile 1858 ff) */ @Override public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) { diff --git a/src/de/dhbwstuttgart/syntaxtree/type/GenericTypeVar.java b/src/de/dhbwstuttgart/syntaxtree/type/GenericTypeVar.java index eb77fa2e8..c153ebd31 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/GenericTypeVar.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/GenericTypeVar.java @@ -15,6 +15,8 @@ import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.SingleConstraint; import de.dhbwstuttgart.typeinference.TypeInsertable; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; +import de.dhbwstuttgart.typeinference.exceptions.DebugException; +import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint; import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.syntaxtree.Class; @@ -203,14 +205,28 @@ public class GenericTypeVar extends Type */ public ConstraintsSet TYPE(TypeAssumptions ass){ ConstraintsSet ret = new ConstraintsSet(); + ass.addGenericVarAssumption(this); return ret; } + @Override + public ConstraintType TYPE(TypeAssumptions ass, SyntaxTreeNode parent) { + ass.addGenericVarAssumption(this); //Eine GenericTypeVar kann nur an Stellen vorkommen, an denen sie auch gültig ist. Daher kann sie den Assumptions hinzugefügt werden. + return super.TYPE(ass, parent); + } + public int getEndOffset() { return this.getOffset() + this.name.toString().length(); } - + + public void setParentClass(Class parent){ + //TODO: Die Methode sollte mit neuem Parser raus und dafür nur noch im Konstruktor gesetzt werden. + this.parent = parent; + } + public Class getParentClass() { + if(this.parent == null) + throw new DebugException("GenericTypeVar ohne Elternelement"); return this.parent; } diff --git a/src/de/dhbwstuttgart/typeinference/Overloading.java b/src/de/dhbwstuttgart/typeinference/Overloading.java index 3db305e90..e3a48f24f 100755 --- a/src/de/dhbwstuttgart/typeinference/Overloading.java +++ b/src/de/dhbwstuttgart/typeinference/Overloading.java @@ -27,7 +27,7 @@ public class Overloading{ * methodCall : type * @param ass * @param method - * @param type - eine Type-Assumption/oder Type für den Rückgabetyp des MethodCall + * @param type - eine Typ-Assumption/oder Typ für den Rückgabetyp des MethodCall */ public Overloading(TypeAssumptions ass, MethodCall method, Type type){ assumptions = ass.clone(); @@ -62,6 +62,7 @@ public class Overloading{ } Vector methodAssumptions = assumptions.getMethodAssumptions(methodCall.getName(), parameterList); if(methodAssumptions.size()==0)throw new TypeinferenceException("Eine Methode "+methodCall.get_Name()+" ist in den Assumptions nicht vorhanden", methodCall); + //Alle möglichen Methoden durchgehen: for(MethodAssumption methodAssumption : methodAssumptions){ if(!(this.type instanceof TypePlaceholder) && !this.type.equals(methodAssumption.getAssumedType()))break; UndConstraint methodConstraint = new UndConstraint(); @@ -69,27 +70,16 @@ public class Overloading{ methodConstraint.addConstraint(methodAssumption.getAssumedType().TYPE(assumptions, methodCall), type.TYPE(assumptions, methodCall)); //Ein Constraint für die Parameter der Methode... for(int i=0; i parameterAssumptions = new Vector(); - parameterAssumptions.add(methodAssumption.getAssumedType()); - for(CParaTypeAssumption pAss : methodAssumption.getParaAssumptions() ){ - parameterAssumptions.add(pAss.getAssumedType()); - } - */ //Ein Constraint für den Receiver der Methode (falls vorhanden)... - //ret.add(new Constraint(methodCall.get_Receiver().get_Expr().getTypeVariable(), new RefType(assumption.getClassName(), null, 0))); - if(methodCall.get_Receiver() != null && methodCall.get_Receiver().get_Expr() != null) + if(methodCall.get_Receiver() != null && methodCall.get_Receiver().get_Expr() != null){ //TODO: FunN-MethodAssumption darf keine Klasse (Class) als ParentClass besitzen. Denn der Typ der Klasse steht noch nicht fest (bisher ist es immer "FunN"). methodConstraint.addConstraint(methodCall.get_Receiver().get_Expr().getType().TYPE(assumptions, methodCall), methodAssumption.getParentClassType().TYPE(assumptions, methodCall)); - //ret.add(new Constraint(methodCall.get_Receiver().get_Expr().getTypeVariable(), new RefType(assumption.getClassName(), parameterAssumptions, 0))); - - //return ret; //Bereits nach der ersten Assumption abbrechen... + } ret.addConstraint(methodConstraint); } return ret; diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/TypeAssumptions.java b/src/de/dhbwstuttgart/typeinference/assumptions/TypeAssumptions.java index 0a67ec5fc..ae128ffd2 100755 --- a/src/de/dhbwstuttgart/typeinference/assumptions/TypeAssumptions.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/TypeAssumptions.java @@ -267,8 +267,6 @@ public class TypeAssumptions { return ret; } - - @Override public String toString(){ String ret = "this: "+this.thisClassName+"\n"; @@ -283,7 +281,6 @@ public class TypeAssumptions { return ret; } - /** * Kontrolliert den vom Parser gesetzten Typ. * Erweitert dessen Bezeichnung, wenn nötig. diff --git a/test/plugindevelopment/TypeInsertTests/LambdaTest24.jav b/test/plugindevelopment/TypeInsertTests/LambdaTest24.jav new file mode 100644 index 000000000..ede3dbe6f --- /dev/null +++ b/test/plugindevelopment/TypeInsertTests/LambdaTest24.jav @@ -0,0 +1,10 @@ +class Overloading_in_Method { + + ff (x) { + op; + op = (m) -> (f) -> f.apply(m); + return op; + } + + +} \ No newline at end of file diff --git a/test/plugindevelopment/TypeInsertTests/LambdaTest24.java b/test/plugindevelopment/TypeInsertTests/LambdaTest24.java new file mode 100644 index 000000000..59de42e50 --- /dev/null +++ b/test/plugindevelopment/TypeInsertTests/LambdaTest24.java @@ -0,0 +1,16 @@ +package plugindevelopment.TypeInsertTests; + +import java.util.Vector; + +import org.junit.Test; + +public class LambdaTest24 { + private static final String TEST_FILE = "LambdaTest24.jav"; + + @Test + public void run(){ + Vector mustContain = new Vector(); + //mustContain.add("Matrix ret"); + MultipleTypesInsertTester.testSingleInsert(this.TEST_FILE, mustContain); + } +}