forked from JavaTX/JavaCompilerCore
151 lines
4.2 KiB
Java
151 lines
4.2 KiB
Java
|
package typinferenz;
|
|||
|
|
|||
|
|
|||
|
import java.util.Iterator;
|
|||
|
import java.util.Vector;
|
|||
|
|
|||
|
import mycompiler.mytype.GenericTypeVar;
|
|||
|
import mycompiler.mytype.RefType;
|
|||
|
import mycompiler.mytype.Type;
|
|||
|
import mycompiler.mytype.TypePlaceholder;
|
|||
|
import mycompiler.mytypereconstruction.replacementlistener.CReplaceTypeEvent;
|
|||
|
import mycompiler.mytypereconstruction.replacementlistener.ITypeReplacementListener;
|
|||
|
import mycompiler.mytypereconstruction.typeassumption.CMethodTypeAssumption;
|
|||
|
|
|||
|
/**
|
|||
|
* @see Spezifikation "Complete Typeinference in Java 8" von Martin Pl<EFBFBD>micke
|
|||
|
* "interface FunN<R,T1, T2, ... ,TN> { R apply(T1 arg1, T2 arg2, ... , TN argN); }"
|
|||
|
* @author A10023 - Andreas Stadelmeier
|
|||
|
*
|
|||
|
*/
|
|||
|
public class FunN extends RefType implements ITypeReplacementListener{
|
|||
|
|
|||
|
private Type R;
|
|||
|
private Vector<Type> T;
|
|||
|
|
|||
|
/**
|
|||
|
* @author Andreas Stadelmeier, a10023
|
|||
|
* Ben<EFBFBD>tigt f<EFBFBD>r den Typinferenzalgorithmus f<EFBFBD>r Java 8
|
|||
|
* Generiert einen RefType auf eine FunN<R,T1,...,TN> - Klasse.
|
|||
|
* @param R
|
|||
|
* @param T
|
|||
|
* @return
|
|||
|
*/
|
|||
|
public FunN(Type R, Vector<Type> T) {
|
|||
|
super("",null,0);
|
|||
|
if(T==null || R == null)throw new NullPointerException();
|
|||
|
setT(T);
|
|||
|
setR(R);
|
|||
|
this.name = "Fun"+T.size();//getName();
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Erstellt eine FunN:
|
|||
|
* FunN<R, T1, ..., TparameterCount>
|
|||
|
* R und T1 - TparameterCount werden mit TypePlaceholdern besetzt.
|
|||
|
* @param parameterCount
|
|||
|
*/
|
|||
|
public FunN(int parameterCount) {
|
|||
|
super("",null,0);
|
|||
|
if(parameterCount<0)throw new RuntimeException("Anzahl der Parameter muss >0 sein");
|
|||
|
Vector<Type> t = new Vector<Type>();
|
|||
|
for(int i=0;i<parameterCount;i++){
|
|||
|
t.add(TypePlaceholder.fresh(this));
|
|||
|
}
|
|||
|
setR(TypePlaceholder.fresh(this));
|
|||
|
setT(t);
|
|||
|
|
|||
|
this.name = "Fun"+parameterCount;
|
|||
|
/*
|
|||
|
Vector<Type> t = new Vector<Type>();
|
|||
|
for(int i=0;i<parameterCount;i++){
|
|||
|
t.add(TypePlaceholder.fresh(this));
|
|||
|
}
|
|||
|
R = TypePlaceholder.fresh(this);
|
|||
|
T = t;
|
|||
|
this.name = getName();
|
|||
|
*/
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Muss nach jeder <EFBFBD>nderung von T oder R aufgerufen werden.
|
|||
|
* Dabei werden bestimmte, von RefType geerbte, Parameter angepasst. Dies ist wichtig f<EFBFBD>r den Typinferenzalgorithmus.
|
|||
|
*/
|
|||
|
private void calculateNewParalist(){
|
|||
|
Vector<Type> t = new Vector<Type>();
|
|||
|
if(R!=null)t.add(R);
|
|||
|
if(T!=null)t.addAll(T);
|
|||
|
this.set_ParaList(t);
|
|||
|
}
|
|||
|
|
|||
|
protected void setT(Vector<Type> T){
|
|||
|
this.T = T;
|
|||
|
calculateNewParalist();
|
|||
|
//ReplacementListener registrieren:
|
|||
|
for(Type t : T)if(t instanceof TypePlaceholder)((TypePlaceholder)t).addReplacementListener(this);
|
|||
|
}
|
|||
|
protected void setR(Type R){
|
|||
|
this.R = R;
|
|||
|
calculateNewParalist();
|
|||
|
//Sind die <20>bergebenen Typen TypePlaceholder, so soll die FunN <20>ber TypReplacements informiert werden.
|
|||
|
if(R instanceof TypePlaceholder){
|
|||
|
((TypePlaceholder)R).addReplacementListener(this);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
@Override
|
|||
|
public String getName(){
|
|||
|
String ret = "FunN<"+R.toString();
|
|||
|
for(Type t : T){
|
|||
|
ret += ", " + t.toString();
|
|||
|
}
|
|||
|
ret += ">";
|
|||
|
return ret;
|
|||
|
}
|
|||
|
*/
|
|||
|
public void replaceType(CReplaceTypeEvent e) {
|
|||
|
if(R.equals(e.getOldType()))R=e.getNewType();
|
|||
|
for(Type t : T){
|
|||
|
if(t.equals(e.getOldType()))T.setElementAt(e.getNewType(),T.indexOf(t));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public int getTypeLineNumber() {
|
|||
|
// TODO Auto-generated method stub
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
public CMethodTypeAssumption toCMethodTypeAssumption() {
|
|||
|
CMethodTypeAssumption ret = new CMethodTypeAssumption(this, "apply", R, this.T.size(), 0,this.getOffset(),new Vector<Integer>(),null);
|
|||
|
for(Type t : T){
|
|||
|
ret.addParaAssumption(TypeAssumptions.createCParaTypeAssumption(t.get_Name(), t));
|
|||
|
}
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
@Override
|
|||
|
public JavaCodeResult printJavaCode(ResultSet resultSet){
|
|||
|
//String ret = super.printJavaCode(resultSet) + (T!=null ? this.T.size() : 0) +"<";
|
|||
|
JavaCodeResult ret = new JavaCodeResult("Fun" + (T!=null ? this.T.size() : 0) +"<");
|
|||
|
ret .attach( this.R.printJavaCode(resultSet)).attach(", ");
|
|||
|
Iterator<Type> it = T.iterator();
|
|||
|
while(it.hasNext()){
|
|||
|
Type t = it.next();
|
|||
|
ret.attach( t.printJavaCode(resultSet));
|
|||
|
if(it.hasNext())ret.attach(", ");
|
|||
|
}
|
|||
|
//ret = ret.substring(0, ret.length()-2);
|
|||
|
return ret.attach(">");
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Ein <EFBFBD>berschreiben der clone-Methode ist notwendig, da sonst beim Unify-Algorithmus die Clone-Methode der Superklasse "RefType" ausgef<EFBFBD>hrt wird.
|
|||
|
*/
|
|||
|
@Override
|
|||
|
public RefType clone()
|
|||
|
{
|
|||
|
return new FunN(this.R,this.T);
|
|||
|
}
|
|||
|
}
|