forked from JavaTX/JavaCompilerCore
178 lines
5.0 KiB
Java
Executable File
178 lines
5.0 KiB
Java
Executable File
package typinferenz;
|
|
|
|
|
|
import java.util.Iterator;
|
|
import java.util.Vector;
|
|
|
|
import mycompiler.myclass.Method;
|
|
import mycompiler.myclass.ParameterList;
|
|
import typinferenz.assumptions.MethodAssumption;
|
|
import typinferenz.assumptions.TypeAssumptions;
|
|
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ümicke
|
|
* "interface FunN<R,T1, T2, ... ,TN> { R apply(T1 arg1, T2 arg2, ... , TN argN); }"
|
|
* @author A10023 - Andreas Stadelmeier
|
|
*
|
|
* Bemerkung:
|
|
* FunN ist ein RefType. Der RefType ist nicht mit einem FunNInterface verbunden.
|
|
*
|
|
*/
|
|
public class FunN extends RefType implements ITypeReplacementListener{
|
|
|
|
private Type R;
|
|
private Vector<Type> T;
|
|
|
|
/**
|
|
* @author Andreas Stadelmeier, a10023
|
|
* Benötigt für den Typinferenzalgorithmus fü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 Änderung von T oder R aufgerufen werden.
|
|
* Dabei werden bestimmte, von RefType geerbte, Parameter angepasst. Dies ist wichtig fü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 übergebenen Typen TypePlaceholder, so soll die FunN ü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()))this.setR(e.getNewType());
|
|
for(Type t : T){
|
|
if(t.equals(e.getOldType())){
|
|
T.setElementAt(e.getNewType(),T.indexOf(t));
|
|
this.setT(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);
|
|
MethodAssumption ret = null;
|
|
Method method = new Method();
|
|
method.set_Method_Name(this.getName());
|
|
ParameterList paraList = new ParameterList();
|
|
method.setParameterList(this.get_ParaList().clone());
|
|
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(">");
|
|
}
|
|
|
|
/**
|
|
* Die Clone-Methode von RefType darf von FunN NICHT überschrieben werden.
|
|
@Override
|
|
public FunN clone()
|
|
{
|
|
FunN ret = null;
|
|
Vector<Type> clonepara = new Vector<Type>();
|
|
for(int i = 0; i< this.T.size(); i++)
|
|
{
|
|
clonepara.addElement(((Type)this.T.elementAt(i)).clone());
|
|
}
|
|
|
|
ret = new FunN(this.R.clone(),clonepara);
|
|
ret.setPrimitiveFlag(this.getPrimitiveFlag());
|
|
return ret;
|
|
}
|
|
*/
|
|
}
|