this()-Aufruf anfügen

This commit is contained in:
JanUlrich 2015-02-26 15:50:23 +01:00
parent 5455ba803e
commit 1941fa5d64
9 changed files with 90 additions and 53 deletions

View File

@ -1852,14 +1852,14 @@ case 146:
case 147: case 147:
// line 1224 "./../src/de/dhbwstuttgart/parser/JavaParser.jay" // line 1224 "./../src/de/dhbwstuttgart/parser/JavaParser.jay"
{ {
This THCON = new This(((Token)yyVals[-3+yyTop]).getOffset(),((Token)yyVals[-3+yyTop]).getLexem().length()); ThisCall THCON = new ThisCall(((Token)yyVals[-3+yyTop]).getOffset(),((Token)yyVals[-3+yyTop]).getLexem().length());
yyVal=THCON; yyVal=THCON;
} }
break; break;
case 148: case 148:
// line 1229 "./../src/de/dhbwstuttgart/parser/JavaParser.jay" // line 1229 "./../src/de/dhbwstuttgart/parser/JavaParser.jay"
{ {
This THCONargl = new This(((Token)yyVals[-4+yyTop]).getOffset(),((Token)yyVals[-4+yyTop]).getLexem().length()); ThisCall THCONargl = new ThisCall(((Token)yyVals[-4+yyTop]).getOffset(),((Token)yyVals[-4+yyTop]).getLexem().length());
THCONargl.set_ArgumentList(((ArgumentList)yyVals[-2+yyTop])); THCONargl.set_ArgumentList(((ArgumentList)yyVals[-2+yyTop]));
yyVal=THCONargl; yyVal=THCONargl;
} }

View File

@ -1222,12 +1222,12 @@ formalparameterlist :formalparameter
explicitconstructorinvocation : THIS '(' ')' ';' explicitconstructorinvocation : THIS '(' ')' ';'
{ {
This THCON = new This($1.getOffset(),$1.getLexem().length()); ThisCall THCON = new ThisCall($1.getOffset(),$1.getLexem().length());
$$=THCON; $$=THCON;
} }
|THIS '(' argumentlist ')' ';' |THIS '(' argumentlist ')' ';'
{ {
This THCONargl = new This($1.getOffset(),$1.getLexem().length()); ThisCall THCONargl = new ThisCall($1.getOffset(),$1.getLexem().length());
THCONargl.set_ArgumentList($3); THCONargl.set_ArgumentList($3);
$$=THCONargl; $$=THCONargl;
} }

View File

@ -43,6 +43,7 @@ public class Constructor extends Method {
ret.addAssumption(new ConstructorAssumption(this, parentClass)); ret.addAssumption(new ConstructorAssumption(this, parentClass));
return ret; return ret;
} }
/*
@Override @Override
public void parserPostProcessing(SyntaxTreeNode parent){ public void parserPostProcessing(SyntaxTreeNode parent){
if(this.parameterlist != null){ if(this.parameterlist != null){
@ -54,6 +55,7 @@ public class Constructor extends Method {
gtv.parserPostProcessing(this); gtv.parserPostProcessing(this);
} }
} }
*/
@Override @Override
public ConstraintsSet TYPE(TypeAssumptions ass) { public ConstraintsSet TYPE(TypeAssumptions ass) {
//super.setType(this.getParentClass().getType()); //super.setType(this.getParentClass().getType());
@ -62,7 +64,8 @@ public class Constructor extends Method {
} }
@Override @Override
public void setType(Type t) { public void setType(Type t) {
throw new TypeinferenceException("Einem Konstruktor kann kein Typ zugewiesen werden", this); super.setType(new Void(this, this.getOffset()));
//throw new TypeinferenceException("Einem Konstruktor kann kein Typ zugewiesen werden", this);
//this.methode.setType(t); //this.methode.setType(t);
} }
/* /*

View File

@ -6,7 +6,6 @@ import java.util.Hashtable;
import java.util.Vector; import java.util.Vector;
import de.dhbwstuttgart.logger.Logger; import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.bytecode.ClassFile; import de.dhbwstuttgart.bytecode.ClassFile;
import de.dhbwstuttgart.bytecode.CodeAttribute; import de.dhbwstuttgart.bytecode.CodeAttribute;
import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.myexception.JVMCodeException;
@ -17,11 +16,16 @@ import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.Type; import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.ConstraintType;
import de.dhbwstuttgart.typeinference.ConstraintsSet; import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.OderConstraint;
import de.dhbwstuttgart.typeinference.Overloading; import de.dhbwstuttgart.typeinference.Overloading;
import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.UndConstraint;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
@ -202,11 +206,67 @@ public class MethodCall extends Expr
} }
//Noch das Overloading-Constraint anhängen: //Noch das Overloading-Constraint anhängen:
ret.add(new Overloading(assumptions, this, this.getType()).generateConsstraints()); ret.add(overloading(assumptions));
return ret; return ret;
} }
/**
* Erstellt die Constraints für den eigentlichen Methodenaufruf.
* Sucht in den Assumptions nach passenden Methoden und erstellt ein OderConstraintSet.
* @param assumptions
* @return
*/
ConstraintsSet overloading(TypeAssumptions assumptions){
ConstraintsSet ret = new ConstraintsSet();
//ret.add(new Overloading(assumptions, this, this.getType()).generateConsstraints());
OderConstraint oCons = new OderConstraint();
Vector<MethodAssumption> methodAssumptions = assumptions.getMethodAssumptions(this.getName(), this.getArgumentList().size());
if(methodAssumptions.size()==0)throw new TypeinferenceException("Eine Methode "+this.get_Name()+" ist in den Assumptions nicht vorhanden", this);
//Alle möglichen Methoden durchgehen:
for(MethodAssumption methodAssumption : methodAssumptions){
//Constraint nicht erstellen, falls Rückgabetyp von vorne herein nicht übereinstimmt:
if(!(this.type instanceof TypePlaceholder) && !this.type.equals(methodAssumption.getAssumedType()))break;
oCons.addConstraint(constraintsFromMethodAssumption(methodAssumption, assumptions));
}
return ret;
}
/**
* Spezifikation:
* overloading determines for all possible overloadings and overridings
* of a method the constraints, where constraints itself forms
* the constraints from the receiver type, the argument types, the return
* type and a given type assumption for the method. If it is a
* method from a class, which is not the actual class (this), all type
* variables are replaced by fresh type variables (fresh), as different
* instances can occur. sargs determines all type assumptions of a
* method, where the argument types are supertypes of a minimal type
* assumption.
*
* @TODO: wenn es sich um eine Methode einer anderen Klasse handelt, müssen neue TPH vergeben werden und nicht die der Assumption verwendet werden.
*
* @return
*/
UndConstraint constraintsFromMethodAssumption(MethodAssumption methodAssumption, TypeAssumptions assumptions){
UndConstraint methodConstraint = new UndConstraint();
//Ein Constraint für den ReturnType der Methode...
methodConstraint.addConstraint(methodAssumption.getAssumedType().TYPE(assumptions, this), type.TYPE(assumptions, this));
//Ein Constraint für die Parameter der Methode...
for(int i=0; i<methodAssumption.getParaCount();i++){
//Type der Argument Expressions <. AssumedType der Parameter
ConstraintType ct1 = this.getArgumentList().argumentAt(i).getType().TYPE(assumptions, this);
ConstraintType ct2 = methodAssumption.getParameterType(i).TYPE(assumptions, this);
methodConstraint.addConstraint(ct1 , ct2);
}
//Ein Constraint für den Receiver der Methode (falls vorhanden)...
if(this.get_Receiver() != null && this.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(this.get_Receiver().get_Expr().getType().TYPE(assumptions, this), methodAssumption.getParentClassType().TYPE(assumptions, this));
}
return methodConstraint;
}
/** /**
* Spezifikation: * Spezifikation:
* TYPEStmt( Ass, stmt ) = * TYPEStmt( Ass, stmt ) =

View File

@ -19,9 +19,12 @@ import de.dhbwstuttgart.syntaxtree.misc.UsedId;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type; import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.ConstraintsSet; import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.Overloading;
import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.assumptions.ConstructorAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet;
@ -127,24 +130,9 @@ public class This extends Expr
return ret; return ret;
} }
/**
* This kann auch als Konstruktoraufruf in einem Konstruktor-Block vorkommen.
*/
@Override @Override
public ConstraintsSet TYPEStmt(TypeAssumptions assumptions) { public ConstraintsSet TYPEStmt(TypeAssumptions assumptions) {
ConstraintsSet ret = new ConstraintsSet(); throw new TypeinferenceException("this ist keine Anweisung", this);
//Kontrollieren, dass sich this(...) in einem Konstruktor und dort als erstes Statement befindet:
SyntaxTreeNode p = this.getGTVDeclarationContext();
if(p instanceof Constructor &&
((Constructor)p).get_Block().statements.firstElement().equals(this)){
//Constraints generieren:
MethodCall constructorCall = new MethodCall(new Receiver(this), this.getParentClass().getName().toString(), arglist, this.getOffset());
ret.add(constructorCall.TYPEStmt(assumptions));
return ret;
}else{
//Ansonsten Fehler ausgeben:
throw new TypeinferenceException("This()-Aufruf hier nicht möglich", this);
}
} }
public String toString() public String toString()
@ -167,4 +155,3 @@ public class This extends Expr
} }
} }
// ino.end

View File

@ -53,8 +53,8 @@ public class Overloading{
* @TODO: wenn es sich um eine Methode einer anderen Klasse handelt, müssen neue TPH vergeben werden und nicht die der Assumption verwendet werden. * @TODO: wenn es sich um eine Methode einer anderen Klasse handelt, müssen neue TPH vergeben werden und nicht die der Assumption verwendet werden.
* *
* @return * @return
*/
public OderConstraint generateConsstraints(){ public OderConstraint generateConsstraints_old(){
OderConstraint ret = new OderConstraint(); OderConstraint ret = new OderConstraint();
Vector<Type> parameterList = new Vector<Type>(); Vector<Type> parameterList = new Vector<Type>();
for(Expr argument : methodCall.getArgumentList().expr){ for(Expr argument : methodCall.getArgumentList().expr){
@ -64,25 +64,13 @@ public class Overloading{
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: //Alle möglichen Methoden durchgehen:
for(MethodAssumption methodAssumption : methodAssumptions){ for(MethodAssumption methodAssumption : methodAssumptions){
//Constraint nicht erstellen, falls Rückgabetyp von vorne herein nicht übereinstimmt:
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(); ret.addConstraint(constraintsFromMethodAssumption(methodAssumption));
//Ein Constraint für den ReturnType der Methode...
methodConstraint.addConstraint(methodAssumption.getAssumedType().TYPE(assumptions, methodCall), type.TYPE(assumptions, methodCall));
//Ein Constraint für die Parameter der Methode...
for(int i=0; i<methodAssumption.getParaCount();i++){
//Type der Argument Expressions <. AssumedType der Parameter
ConstraintType ct1 = methodCall.getArgumentList().argumentAt(i).getType().TYPE(assumptions, methodCall);
ConstraintType ct2 = methodAssumption.getParameterType(i).TYPE(assumptions, methodCall);
methodConstraint.addConstraint(ct1 , ct2);
}
//Ein Constraint für den Receiver der Methode (falls vorhanden)...
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.addConstraint(methodConstraint);
} }
return ret; return ret;
} }
*/
} }

View File

@ -8,14 +8,16 @@ import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
import de.dhbwstuttgart.syntaxtree.type.Type; import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.exceptions.DebugException; import de.dhbwstuttgart.typeinference.exceptions.DebugException;
import de.dhbwstuttgart.syntaxtree.type.*;
public class ConstructorAssumption extends MethodAssumption{ public class ConstructorAssumption extends MethodAssumption{
public ConstructorAssumption(Method assumedMethod, Class parentClass) { public ConstructorAssumption(Method assumedMethod, Class parentClass) {
super(assumedMethod, parentClass); super(assumedMethod, parentClass);
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof ConstructorAssumption))return false; if(!(obj instanceof ConstructorAssumption))return false;
@ -24,7 +26,8 @@ public class ConstructorAssumption extends MethodAssumption{
@Override @Override
public Type getAssumedType() { public Type getAssumedType() {
throw new DebugException("Eine ConstructorAssumption hat keinen Typ bzw. er ist nicht relevant"); return new Void(this.method, this.method.getOffset());
//throw new DebugException("Eine ConstructorAssumption hat keinen Typ bzw. er ist nicht relevant");
//return this.getMethod().getParentClass().getType(); //return this.getMethod().getParentClass().getType();
} }

View File

@ -9,7 +9,7 @@ import de.dhbwstuttgart.syntaxtree.type.Type;
public class MethodAssumption extends FieldAssumption { public class MethodAssumption extends FieldAssumption {
private Method method; protected Method method;
private Class parentClass; private Class parentClass;
public MethodAssumption(Method assumedMethod, Class parentClass){ public MethodAssumption(Method assumedMethod, Class parentClass){

View File

@ -120,15 +120,13 @@ public class TypeAssumptions {
/** /**
* Sucht nach Assumptions zu einer Methode mit dem Namen methodName und parameterCount Parametern. * Sucht nach Assumptions zu einer Methode mit dem Namen methodName und parameterCount Parametern.
* @param methodName * @param methodName
* @param parameter Die Parameter, welche die Methode verarbeiten soll * @param i Die Parameter, welche die Methode verarbeiten soll
* @return Alle Methoden in den Assumptions, welche eine Parameterliste der Länge der übergebenen Parameterliste (parameter) verarbeiten können. * @return Alle Methoden in den Assumptions, welche eine Parameterliste der Länge der übergebenen Parameterliste (parameter) verarbeiten können.
*/ */
public Vector<MethodAssumption> getMethodAssumptions(String methodName, Vector<Type> parameter){ public Vector<MethodAssumption> getMethodAssumptions(String methodName, int parameterCount){
int parameterCount = parameter.size();
Vector<MethodAssumption> ret = new Vector<MethodAssumption>(); Vector<MethodAssumption> ret = new Vector<MethodAssumption>();
for(MethodAssumption ass : this.methodAssumptions){ for(MethodAssumption ass : this.methodAssumptions){
if(ass.getMethodName().equals(methodName) && ass.getParaCount() == parameterCount){ if(ass.getMethodName().equals(methodName) && ass.getParaCount() == parameterCount){
ret.add(ass); ret.add(ass);
} }
} }
@ -375,14 +373,12 @@ public class TypeAssumptions {
/** /**
* *
* @param name
* @param size
* @return Null, falls kein Konstruktor vorhanden. * @return Null, falls kein Konstruktor vorhanden.
*/ */
public ConstructorAssumption getConstructorAssumption(String name, int size) { public ConstructorAssumption getConstructorAssumption(String className, int paramCount) {
for(ConstructorAssumption ca : this.constructorAssumptions){ for(ConstructorAssumption ca : this.constructorAssumptions){
log.debug("Durchsuche Assumptions: "+ca.getIdentifier().toString() +" -Anzahl Parameter: "+ ca.getParaCount(), Section.TYPEINFERENCE); log.debug("Durchsuche Assumptions: "+ca.getIdentifier().toString() +" -Anzahl Parameter: "+ ca.getParaCount(), Section.TYPEINFERENCE);
if(ca.getParaCount()==size && ca.getIdentifier().equals(name))return ca; if(ca.getParaCount()==paramCount && ca.getIdentifier().equals(className))return ca;
} }
return null; return null;
} }