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:
// 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;
}
break;
case 148:
// 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]));
yyVal=THCONargl;
}

View File

@ -1222,12 +1222,12 @@ formalparameterlist :formalparameter
explicitconstructorinvocation : THIS '(' ')' ';'
{
This THCON = new This($1.getOffset(),$1.getLexem().length());
ThisCall THCON = new ThisCall($1.getOffset(),$1.getLexem().length());
$$=THCON;
}
|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;
}

View File

@ -43,6 +43,7 @@ public class Constructor extends Method {
ret.addAssumption(new ConstructorAssumption(this, parentClass));
return ret;
}
/*
@Override
public void parserPostProcessing(SyntaxTreeNode parent){
if(this.parameterlist != null){
@ -54,6 +55,7 @@ public class Constructor extends Method {
gtv.parserPostProcessing(this);
}
}
*/
@Override
public ConstraintsSet TYPE(TypeAssumptions ass) {
//super.setType(this.getParentClass().getType());
@ -62,7 +64,8 @@ public class Constructor extends Method {
}
@Override
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);
}
/*

View File

@ -6,7 +6,6 @@ import java.util.Hashtable;
import java.util.Vector;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.bytecode.ClassFile;
import de.dhbwstuttgart.bytecode.CodeAttribute;
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.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.ConstraintType;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.OderConstraint;
import de.dhbwstuttgart.typeinference.Overloading;
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.exceptions.TypeinferenceException;
@ -202,11 +206,67 @@ public class MethodCall extends Expr
}
//Noch das Overloading-Constraint anhängen:
ret.add(new Overloading(assumptions, this, this.getType()).generateConsstraints());
ret.add(overloading(assumptions));
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:
* 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.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.Overloading;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.assumptions.ConstructorAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet;
@ -127,24 +130,9 @@ public class This extends Expr
return ret;
}
/**
* This kann auch als Konstruktoraufruf in einem Konstruktor-Block vorkommen.
*/
@Override
public ConstraintsSet TYPEStmt(TypeAssumptions assumptions) {
ConstraintsSet ret = new ConstraintsSet();
//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);
}
throw new TypeinferenceException("this ist keine Anweisung", this);
}
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.
*
* @return
*/
public OderConstraint generateConsstraints(){
public OderConstraint generateConsstraints_old(){
OderConstraint ret = new OderConstraint();
Vector<Type> parameterList = new Vector<Type>();
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);
//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;
UndConstraint methodConstraint = new UndConstraint();
//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);
ret.addConstraint(constraintsFromMethodAssumption(methodAssumption));
}
return ret;
}
*/
}

View File

@ -8,14 +8,16 @@ import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
import de.dhbwstuttgart.syntaxtree.type.*;
public class ConstructorAssumption extends MethodAssumption{
public ConstructorAssumption(Method assumedMethod, Class parentClass) {
super(assumedMethod, parentClass);
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof ConstructorAssumption))return false;
@ -24,7 +26,8 @@ public class ConstructorAssumption extends MethodAssumption{
@Override
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();
}

View File

@ -9,7 +9,7 @@ import de.dhbwstuttgart.syntaxtree.type.Type;
public class MethodAssumption extends FieldAssumption {
private Method method;
protected Method method;
private 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.
* @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.
*/
public Vector<MethodAssumption> getMethodAssumptions(String methodName, Vector<Type> parameter){
int parameterCount = parameter.size();
public Vector<MethodAssumption> getMethodAssumptions(String methodName, int parameterCount){
Vector<MethodAssumption> ret = new Vector<MethodAssumption>();
for(MethodAssumption ass : this.methodAssumptions){
if(ass.getMethodName().equals(methodName) && ass.getParaCount() == parameterCount){
ret.add(ass);
}
}
@ -375,14 +373,12 @@ public class TypeAssumptions {
/**
*
* @param name
* @param size
* @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){
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;
}