Probleme mit GenericTypeVar behoben

This commit is contained in:
JanUlrich 2014-09-09 11:15:10 +02:00
parent 6858092ef1
commit 583dfb23e3
12 changed files with 73 additions and 25 deletions

View File

@ -1129,6 +1129,15 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
this.addField(standardKonstruktor); this.addField(standardKonstruktor);
} }
if(this.genericClassParameters == null)this.setGenericParameter(new GenericDeclarationList(new Vector<GenericTypeVar>(), 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) //TODO: Umwandlung zu RefTypes funktioniert noch nicht richtig. (siehe LambdaTest2)
//Als RefType geparste Generische Variablen umwandeln: //Als RefType geparste Generische Variablen umwandeln:
this.wandleRefTypeAttributes2GenericAttributes(); this.wandleRefTypeAttributes2GenericAttributes();
@ -1144,6 +1153,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
Vector<SyntaxTreeNode> ret = new Vector<SyntaxTreeNode>(); Vector<SyntaxTreeNode> ret = new Vector<SyntaxTreeNode>();
for(Field f : this.getFields()){ for(Field f : this.getFields()){
ret.add(f); ret.add(f);
ret.addAll(this.getGenericParameter());
} }
return ret; return ret;
} }
@ -1158,7 +1168,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
} }
@Override @Override
public Iterable<GenericTypeVar> getGenericParameter() { public Vector<GenericTypeVar> getGenericParameter() {
if(this.genericClassParameters == null)return new Vector<GenericTypeVar>(); if(this.genericClassParameters == null)return new Vector<GenericTypeVar>();
return this.genericClassParameters; return this.genericClassParameters;
} }

View File

@ -54,7 +54,7 @@ public abstract class Field extends SyntaxTreeNode implements TypeInsertable, Ty
throws JVMCodeException; throws JVMCodeException;
@Override @Override
public Iterable<GenericTypeVar> getGenericParameter() { public Vector<GenericTypeVar> getGenericParameter() {
Vector<GenericTypeVar> ret = new Vector<>(); Vector<GenericTypeVar> ret = new Vector<>();
if(this.genericParameters == null)return ret; if(this.genericParameters == null)return ret;
ret.addAll(this.genericParameters); ret.addAll(this.genericParameters);
@ -154,9 +154,15 @@ public abstract class Field extends SyntaxTreeNode implements TypeInsertable, Ty
} }
} }
@Override
public Vector<SyntaxTreeNode> getChildren() {
Vector<SyntaxTreeNode> ret = new Vector<>();
if(this.getType()!=null)ret.add(this.getType());
return ret;
}
@Override @Override
public void setGenericParameter(GenericDeclarationList params) { public void setGenericParameter(GenericDeclarationList params) {
this.genericParameters = params; this.genericParameters = params;
} }
} }

View File

@ -106,7 +106,7 @@ public class FieldDeclaration extends Field{
@Override @Override
public Vector<SyntaxTreeNode> getChildren() { public Vector<SyntaxTreeNode> getChildren() {
Vector<SyntaxTreeNode> ret = new Vector<SyntaxTreeNode>(); Vector<SyntaxTreeNode> ret = super.getChildren();
if(this.wert!=null)ret.add(this.wert); if(this.wert!=null)ret.add(this.wert);
return ret; return ret;
} }

View File

@ -683,6 +683,7 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
for(FormalParameter param : this.parameterlist){ for(FormalParameter param : this.parameterlist){
ret.add(param); ret.add(param);
} }
ret.addAll(this.getGenericParameter());
return ret; return ret;
} }

View File

@ -30,7 +30,8 @@ public abstract class SyntaxTreeNode implements IItemWithOffset{
*/ */
public void parserPostProcessing(SyntaxTreeNode parent) { public void parserPostProcessing(SyntaxTreeNode parent) {
this.parent = 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() { public SyntaxTreeNode getParent() {

View File

@ -423,6 +423,7 @@ public class LocalVarDecl extends Statement implements TypeInsertable
@Override @Override
public Vector<SyntaxTreeNode> getChildren() { public Vector<SyntaxTreeNode> getChildren() {
Vector<SyntaxTreeNode> ret = new Vector<SyntaxTreeNode>(); Vector<SyntaxTreeNode> ret = new Vector<SyntaxTreeNode>();
if(this.getType()!=null)ret.add(this.getType());
return ret; return ret;
} }

View File

@ -175,7 +175,7 @@ public class MethodCall extends Expr
* Mögliche Probleme: * Mögliche Probleme:
* Wenn die Methode ohne Angabe eines Receivers im Quelltext steht: * Wenn die Methode ohne Angabe eines Receivers im Quelltext steht:
* methodCall(param); -> (bedeutet:) this.methodCall(param); * 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 @Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) { public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {

View File

@ -15,6 +15,8 @@ import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.SingleConstraint; import de.dhbwstuttgart.typeinference.SingleConstraint;
import de.dhbwstuttgart.typeinference.TypeInsertable; import de.dhbwstuttgart.typeinference.TypeInsertable;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; 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.typeinference.typedeployment.TypeInsertPoint;
import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.parser.JavaClassName;
import de.dhbwstuttgart.syntaxtree.Class; import de.dhbwstuttgart.syntaxtree.Class;
@ -203,14 +205,28 @@ public class GenericTypeVar extends Type
*/ */
public ConstraintsSet TYPE(TypeAssumptions ass){ public ConstraintsSet TYPE(TypeAssumptions ass){
ConstraintsSet ret = new ConstraintsSet(); ConstraintsSet ret = new ConstraintsSet();
ass.addGenericVarAssumption(this);
return ret; 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() { public int getEndOffset() {
return this.getOffset() + this.name.toString().length(); 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() { public Class getParentClass() {
if(this.parent == null)
throw new DebugException("GenericTypeVar ohne Elternelement");
return this.parent; return this.parent;
} }

View File

@ -27,7 +27,7 @@ public class Overloading{
* methodCall : type * methodCall : type
* @param ass * @param ass
* @param method * @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){ public Overloading(TypeAssumptions ass, MethodCall method, Type type){
assumptions = ass.clone(); assumptions = ass.clone();
@ -62,6 +62,7 @@ public class Overloading{
} }
Vector<MethodAssumption> methodAssumptions = assumptions.getMethodAssumptions(methodCall.getName(), parameterList); Vector<MethodAssumption> 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); 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){ for(MethodAssumption methodAssumption : methodAssumptions){
if(!(this.type instanceof TypePlaceholder) && !this.type.equals(methodAssumption.getAssumedType()))break; if(!(this.type instanceof TypePlaceholder) && !this.type.equals(methodAssumption.getAssumedType()))break;
UndConstraint methodConstraint = new UndConstraint(); UndConstraint methodConstraint = new UndConstraint();
@ -69,27 +70,16 @@ public class Overloading{
methodConstraint.addConstraint(methodAssumption.getAssumedType().TYPE(assumptions, methodCall), type.TYPE(assumptions, methodCall)); methodConstraint.addConstraint(methodAssumption.getAssumedType().TYPE(assumptions, methodCall), type.TYPE(assumptions, methodCall));
//Ein Constraint für die Parameter der Methode... //Ein Constraint für die Parameter der Methode...
for(int i=0; i<methodAssumption.getParaCount();i++){ for(int i=0; i<methodAssumption.getParaCount();i++){
//CParaTypeAssumption pAss = assumption.getParaAssumption(i);
//Type der Argument Expressions <. AssumedType der Parameter //Type der Argument Expressions <. AssumedType der Parameter
ConstraintType ct1 = methodCall.getArgumentList().argumentAt(i).getType().TYPE(assumptions, methodCall); ConstraintType ct1 = methodCall.getArgumentList().argumentAt(i).getType().TYPE(assumptions, methodCall);
ConstraintType ct2 = methodAssumption.getParameterType(i).TYPE(assumptions, methodCall); ConstraintType ct2 = methodAssumption.getParameterType(i).TYPE(assumptions, methodCall);
methodConstraint.addConstraint(ct1 , ct2); methodConstraint.addConstraint(ct1 , ct2);
} }
/*
Vector<Type> parameterAssumptions = new Vector<Type>();
parameterAssumptions.add(methodAssumption.getAssumedType());
for(CParaTypeAssumption pAss : methodAssumption.getParaAssumptions() ){
parameterAssumptions.add(pAss.getAssumedType());
}
*/
//Ein Constraint für den Receiver der Methode (falls vorhanden)... //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"). //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)); 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); ret.addConstraint(methodConstraint);
} }
return ret; return ret;

View File

@ -267,8 +267,6 @@ public class TypeAssumptions {
return ret; return ret;
} }
@Override @Override
public String toString(){ public String toString(){
String ret = "this: "+this.thisClassName+"\n"; String ret = "this: "+this.thisClassName+"\n";
@ -283,7 +281,6 @@ public class TypeAssumptions {
return ret; return ret;
} }
/** /**
* Kontrolliert den vom Parser gesetzten Typ. * Kontrolliert den vom Parser gesetzten Typ.
* Erweitert dessen Bezeichnung, wenn nötig. * Erweitert dessen Bezeichnung, wenn nötig.

View File

@ -0,0 +1,10 @@
class Overloading_in_Method {
ff (x) {
op;
op = (m) -> (f) -> f.apply(m);
return op;
}
}

View File

@ -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<String> mustContain = new Vector<String>();
//mustContain.add("Matrix ret");
MultipleTypesInsertTester.testSingleInsert(this.TEST_FILE, mustContain);
}
}